:root{
  /* 2026-09-20 "Apple-minimal" reversal — replaces the previous #d90228-red +
     gold "bold local marketplace" system entirely. Modeled directly on the
     apple.com/mac, /store, /iphone, /watch, /support, /accessories, /airpods
     screenshots reviewed with the user (confirmed twice via AskUserQuestion,
     reinforced by "follow the clean look" on laptopzone1.com): near-total
     desaturation, one blue accent, huge whitespace, no colored badges. The
     old tokens are gone, not just unused — anything still reading --brand/
     --deal-accent/etc. below now resolves to the new neutral system so no
     component silently reverts to red/gold.

     --ink / --ink-soft / --muted map to Apple's #1d1d1f (near-black text) and
     #6e6e73 (secondary/muted grey) exactly as shown in every screenshot's
     body copy and eyebrow text. --paper is Apple's #f5f5f7 signature
     alternating light-grey section background (used between white sections
     for rhythm, e.g. the "Explore the lineup" band on apple.com/mac). --line
     /--line-strong are Apple's near-invisible #d2d2d7-ish dividers — sections
     are mostly separated by background-color/whitespace, not borders.
     --brand is now the ONE accent color (#0071e3, Apple's real link/button
     blue) — used only for links ("Learn more >") and primary pill buttons,
     never for decorative fills, badges, or backgrounds. --brand-ink is a
     slightly deeper blue for hover/active states (Apple darkens its blue on
     hover, doesn't introduce a second hue). --brand-soft is a very light
     blue tint for focus rings/selection only. --accent2 is kept defined
     (still referenced by a couple of low-priority tertiary spots) but
     pointed at the same blue family so nothing can look "teal" by accident. */
  --ink:#1d1d1f;
  --ink-soft:#424245;
  --paper:#f5f5f7;
  --surface:#ffffff;
  --line:#e8e8ed;
  --line-strong:#d2d2d7;
  --brand:#0071e3;
  --brand-2:#0071e3;
  --brand-ink:#0058b0;
  --brand-soft:#e8f2fe;
  --accent2:#0071e3;
  --muted:#6e6e73;
  --ok:#1d7a3c;
  --ok-bg:#e6f4ea;
  --danger:#c53434;
  --danger-bg:#fbeaea;

  /* Deal/gold tokens kept defined (still referenced by a couple of legacy
     selectors below during the transition) but neutralized to the same
     near-black/grey used for ordinary text — Apple shows "New" or a price
     note as plain colored TEXT, never a gold gradient badge/ribbon. Nothing
     in the redesigned markup below actually paints a gold surface anymore;
     .discount-ribbon itself was removed from product-card-fn.php. */
  --deal-accent:#c5a253;
  --deal-accent-2:#c5a253;
  --deal-ink:#6e6e73;
  --gold-soft:#f5f5f7;
  --warning:#c5a253;
  --warning-bg:#f5f5f7;

  /* Gradients removed as a visual language — Apple uses flat color +
     whitespace, not gradients, for its light UI chrome (dark hero panels are
     photographic, not CSS gradients, and out of scope for this pass). Tokens
     kept defined and pointed at flat colors so any leftover reference still
     renders sanely instead of erroring, but nothing new should use these. */
  --brand-gradient: var(--brand);
  --brand-gradient-soft: var(--paper);
  --gold-gradient: var(--paper);
  --heading-underline-gradient: transparent;

  /* Apple's cards use a bigger, calmer corner radius (~18-20px) and little
     to no drop shadow — shadows below are intentionally much lighter than
     the old --shadow-lg. */
  --radius-sm: 10px;
  --radius: 18px;
  --radius-lg: 20px;
  --shadow-xs: 0 1px 2px rgba(0,0,0,.04);
  --shadow-sm: 0 1px 3px rgba(0,0,0,.06);
  --shadow: 0 2px 12px rgba(0,0,0,.07);
  --shadow-lg: 0 8px 30px rgba(0,0,0,.10);
  --ease: cubic-bezier(.2,.8,.2,1);

  /* Map the palette onto Bootstrap's own CSS variables, so every Bootstrap
     component (buttons, badges, forms, dropdowns...) picks up the new
     Apple-minimal colors automatically instead of needing per-component
     overrides scattered through this file. */
  --bs-primary: var(--brand);
  --bs-primary-rgb: 0,113,227;
  --bs-body-color: var(--ink);
  --bs-body-bg: var(--surface);
  --bs-link-color: var(--brand);
  --bs-link-hover-color: var(--brand-ink);
  --bs-border-color: var(--line);
  --bs-border-radius: var(--radius-sm);
  --bs-border-radius-lg: var(--radius);
  --bs-font-sans-serif: var(--font-body);

  /* Apple's real headings use the same San Francisco family as body text at
     a much larger/bolder size, not a distinct display face — so Plus Jakarta
     Sans is dropped as a separate heading font. Inter (already loaded) is
     the closest practical free equivalent to SF and is now used for both
     headings and body, differentiated purely by size/weight (see h1-h4
     rule below). --font-heading is kept as an alias to --font-body so any
     remaining reference still resolves correctly. */
  --font-body: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-heading: var(--font-body);
}

*{ scrollbar-color: var(--line-strong) transparent; }
body{
  font-family:var(--font-body);
  -webkit-font-smoothing:antialiased;
}
/* Apple headings: same family as body text, distinguished purely by size/
   weight/tight tracking and generous whitespace — no underline decoration,
   no distinct display face (see apple.com/mac's huge left-aligned "Mac"
   page title sitting alone with nothing but whitespace around it). */
h1,h2,h3,h4{ font-family:var(--font-heading); font-weight:700; letter-spacing:-.015em; text-wrap:balance; color:var(--ink); }
a{ text-decoration:none; transition:color .15s var(--ease); color:var(--brand); }
a:hover{ color:var(--brand-ink); }
.price{ font-variant-numeric:tabular-nums; }
::selection{ background:var(--brand-soft); color:var(--brand-ink); }
:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }

.form-select, .form-control{ border-color:var(--line-strong); }
.form-select:focus, .form-control:focus{ border-color:var(--brand); box-shadow:0 0 0 4px var(--brand-soft); }
.card{ border-color:var(--line); }
.badge{ font-weight:600; letter-spacing:.01em; }

/* Apple-minimal section headers ("Shop by Category", "Today's Best Deals",
   etc.): large, confident weight, but no underline bar/gradient — hierarchy
   comes from size + the whitespace around the block, matching the plain
   bold page/section titles seen throughout the apple.com reference
   screenshots (e.g. "Explore the lineup", "Shop iPhone"). */
.block-head h2, section > .container > h2{
  font-size:clamp(26px,3.2vw,40px); font-weight:700; letter-spacing:-.02em; margin-bottom:0;
}

/* ---- Header ---- */
header.site{ background:rgba(255,255,255,.92); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px); border-bottom:1px solid var(--line); }
header.site.sticky-top{ z-index:1040; box-shadow:0 1px 0 rgba(23,19,22,.02); }

/* Contact bar: phone + WhatsApp, sits above the logo/search/actions row.
   Shown on both desktop and mobile; app.js collapses it on mobile scroll
   (see .header-scrolled rules below) to save vertical space. Apple-minimal:
   plain flat --paper background (a subtle neutral utility strip), not a
   colored tint — matches Apple's own plain-grey secondary header rows. */
.header-contact-bar{
  display:flex; align-items:center; gap:20px; padding:8px 0;
  background:var(--paper);
  border-bottom:1px solid var(--line); font-size:12.5px; font-weight:500; color:var(--ink-soft);
  overflow:hidden; max-height:40px; opacity:1;
  transition:max-height .2s var(--ease), opacity .15s var(--ease), padding .2s var(--ease), border-color .2s var(--ease);
}
.header-contact-bar a{ display:flex; align-items:center; gap:7px; color:var(--ink-soft); transition:color .15s var(--ease), transform .12s var(--ease); }
.header-contact-bar a:hover{ color:var(--brand); transform:translateY(-1px); }
/* Small circular icon badge instead of a bare stroked glyph floating in
   the text — gives the phone/WhatsApp links more of a "button" feel. */
.hcb-icon{
  display:flex; align-items:center; justify-content:center; width:20px; height:20px; border-radius:99px;
  background:var(--surface); color:var(--ink-soft); flex-shrink:0; transition:background .15s var(--ease), color .15s var(--ease);
}
.header-contact-bar a:hover .hcb-icon{ background:var(--surface); color:var(--brand); }
.hcb-icon-wa{ color:#1a9c4c; }

/* Social links (YouTube/Instagram) — pushed to the far right of the same
   contact bar via margin-left:auto on the wrapping flex item, so the
   phone/WhatsApp links stay left-aligned as before and this is purely an
   addition, not a reflow of existing content. Icon-only (aria-label
   carries the name) since the bar has no room for label text once this
   is added on narrow widths. */
.hcb-social{ display:flex; align-items:center; gap:8px; margin-left:auto; }
.hcb-social a{ display:flex; }
.hcb-icon-yt{ color:#FF0000; }
/* Instagram's mark is normally a gradient fill; approximated here with a
   solid brand pink close to its middle stop, since .hcb-icon's circular
   badge is already tinted and a full gradient would fight it visually. */
.hcb-icon-ig{ color:#d6249f; }

.logo{
  font-family:var(--font-heading); font-weight:800; font-size:22px; color:var(--brand-ink);
  white-space:nowrap; letter-spacing:-.01em; display:inline-block; max-width:100%;
  overflow:hidden; text-overflow:ellipsis; vertical-align:middle;
}
.logo span{ color:var(--ink); }
/* Logo stays a fixed size at all times — no shrink on scroll or at
   mobile widths (previously did both; user asked to keep it constant).
   .logo's own overflow/ellipsis above is still the safety net if
   "SuperTechSys" at 22px doesn't fit a very narrow column. */
.logo-image{ display:block; height:34px; width:auto; max-width:180px; object-fit:contain; vertical-align:middle; }
.search-box{ position:relative; max-width:440px; }
.search-box input{ padding-left:38px; border-radius:99px; background:var(--paper); border-color:transparent; height:42px; transition:border-color .15s var(--ease), background .15s var(--ease), box-shadow .15s var(--ease); }
.search-box input:focus{ background:var(--surface); border-color:var(--brand); box-shadow:0 0 0 4px var(--brand-soft); }
.search-box svg{ position:absolute; left:13px; top:50%; transform:translateY(-50%); width:15px; height:15px; color:var(--muted); pointer-events:none; }
#search-results{
  position:absolute; top:calc(100% + 8px); left:0; right:0; background:var(--surface);
  border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow-lg); max-height:340px; overflow-y:auto; z-index:1050;
  padding:6px;
}
#search-results a{ display:flex; gap:10px; align-items:center; padding:9px 10px; font-size:13.5px; border-radius:var(--radius-sm); color:var(--ink); transition:background .12s; }
#search-results a:last-child{ border-bottom:none; }
#search-results a:hover{ background:var(--brand-soft); }
#search-results .ph{ width:32px; height:32px; border-radius:6px; background:var(--paper); flex-shrink:0; }

.compare-pill{
  display:flex; align-items:center; gap:6px; padding:8px 14px; border:1px solid var(--line-strong); border-radius:99px;
  background:var(--surface); color:var(--ink); font-size:13.5px; font-weight:500; transition:border-color .15s var(--ease), box-shadow .15s var(--ease), transform .1s var(--ease);
}
.compare-pill:hover{ border-color:var(--brand); color:var(--brand-ink); box-shadow:var(--shadow-xs); }
.compare-pill .n{ background:var(--brand); color:#fff; border-radius:99px; min-width:18px; height:18px; display:inline-flex; align-items:center; justify-content:center; font-size:11px; font-weight:700; padding:0 4px; }
.wa-pill{ display:flex; align-items:center; gap:7px; background:#25D366; color:#fff; padding:9px 16px; border-radius:99px; font-weight:600; font-size:13.5px; box-shadow:0 4px 14px -4px rgba(37,211,102,.55); transition:transform .12s var(--ease), box-shadow .15s var(--ease); }
.wa-pill:hover{ color:#fff; transform:translateY(-1px); box-shadow:0 8px 20px -4px rgba(37,211,102,.6); }

/* Desktop (>=992px, matching .navbar-expand-lg): scrolling down hides the
   contact bar + logo/search/actions row, leaving only nav.main pinned at
   the top of the header — scrolling up brings it straight back.
   Direction-based, driven by .header-hide-top on header.site (app.js,
   "Header (desktop): hide top row on scroll down, reveal on scroll up").
   Distinct from the threshold-based .header-scrolled class mobile uses
   above.
   header.site switches from position:sticky (Bootstrap's .sticky-top, on
   the element in layout.php — still what mobile uses) to position:fixed
   here, specifically so this can't turn into a scroll-feedback loop: a
   sticky element is still part of normal document flow, so collapsing
   part of it changes the document's height at the exact scroll position,
   which the browser reports back as its own scroll delta, which flips the
   direction detection, which un-collapses it again — forever (hit this
   with a max-height collapse approach in testing: confirmed via
   MutationObserver that the class was toggling every animation frame). A
   fixed header is never part of document flow to begin with, so nothing
   it does internally can ever feed back into window.scrollY. body gets
   padding-top to reserve the space fixed positioning removes (kept in
   sync with --header-h, the same custom property the category/finder
   sidebars use for their own top offset — see "Category page filter
   sidebar" below); .header-hide-group (contact bar + logo/search/actions
   row) collapses with max-height/opacity same as before, and since it's
   the *fixed* header collapsing now, not an in-flow one, nav.main simply
   rises to sit right under it — no absolute positioning or height math
   needed on nav.main itself. */
@media (min-width:992px){
  header.site{ position:fixed; top:0; left:0; right:0; }
  /* Only reserve the fixed-header offset on pages that actually have
     header.site (the public front-end) — admin pages (templates/admin/
     layout.php) share this stylesheet but have no fixed header, so without
     :has() scoping here every admin page got a ~122px blank gap above its
     own (non-fixed) .admin-bar for no reason. */
  body:has(header.site){ padding-top:var(--header-h); }
  .header-hide-group{
    max-height:200px;
    transition:max-height .25s var(--ease), opacity .18s var(--ease);
  }
  /* overflow:hidden only while actually collapsing/collapsed — the
     expanded state must stay visible-overflow, since #search-results
     (the live-search dropdown) is an absolutely-positioned descendant
     that extends below .header-hide-group's own box; clipping it there
     hid the dropdown behind the header. */
  header.site.header-hide-top .header-hide-group{
    max-height:0; opacity:0; overflow:hidden;
  }
}

nav.main{ background:var(--ink); }
nav.main .nav-link{ color:#e7e9ec; font-size:13.5px; font-weight:500; padding:13px 16px !important; transition:background .15s, color .15s; }
nav.main .nav-link:hover, nav.main .nav-link:focus{ background:rgba(255,255,255,.08); color:#fff; }
nav.main .dropdown-menu{ border:1px solid var(--line); border-radius:0 var(--radius) var(--radius) var(--radius); box-shadow:var(--shadow-lg); padding:6px; margin-top:0; }
nav.main .dropdown-item{ border-radius:var(--radius-sm); padding:9px 12px; font-size:13.5px; }
nav.main .dropdown-item:hover, nav.main .dropdown-item:focus{ background:var(--brand-soft); color:var(--brand-ink); }

/* The hamburger toggle now lives in .header-actions (light background —
   moved there from the old dark nav.main bar), so it's styled as a
   circular brand-tinted button instead of Bootstrap's bare bordered
   square + background-image icon. It uses 3 real <span> bars (see
   .navbar-toggler-bar) instead of Bootstrap's .navbar-toggler-icon so
   they can morph into an X on open with a pure-CSS transform, keyed off
   the button's own aria-expanded state — no extra JS beyond what
   data-bs-toggle="collapse" already sets. */
.navbar-toggler{
  display:flex; align-items:center; justify-content:center;
  width:42px; height:42px; padding:0; border:none; border-radius:99px;
  background:var(--brand-soft); box-shadow:none;
  transition:background .18s var(--ease), transform .12s var(--ease);
}
.navbar-toggler:hover{ background:var(--brand-soft); transform:translateY(-1px); }
.navbar-toggler:active{ transform:translateY(0); }
.navbar-toggler:focus{ box-shadow:0 0 0 3px var(--brand-soft); }
.navbar-toggler[aria-expanded="true"]{ background:var(--brand); }

.navbar-toggler-bars{ position:relative; width:18px; height:13px; display:inline-block; flex-shrink:0; }
.navbar-toggler-bar{
  position:absolute; left:0; width:18px; height:2px; border-radius:99px;
  background:var(--brand-ink); transition:transform .22s var(--ease), opacity .15s var(--ease), background .18s var(--ease), top .22s var(--ease);
}
.navbar-toggler-bar:nth-child(1){ top:0; }
.navbar-toggler-bar:nth-child(2){ top:5.5px; }
.navbar-toggler-bar:nth-child(3){ top:11px; }
/* Open state: middle bar fades out, top/bottom rotate into an X. Bumping
   top to 5.5px first (matching the middle bar's resting position) keeps
   the rotation pivoting around the button's visual center instead of
   sweeping in from the corner. */
.navbar-toggler[aria-expanded="true"] .navbar-toggler-bar{ background:#fff; }
.navbar-toggler[aria-expanded="true"] .navbar-toggler-bar:nth-child(1){ top:5.5px; transform:rotate(45deg); }
.navbar-toggler[aria-expanded="true"] .navbar-toggler-bar:nth-child(2){ opacity:0; }
.navbar-toggler[aria-expanded="true"] .navbar-toggler-bar:nth-child(3){ top:5.5px; transform:rotate(-45deg); }

/* ---- Homepage hero banner slider (admin-managed, Admin -> Banners) ---- */
.banner-slider{
  position:relative; overflow:hidden;
  background:var(--brand-gradient-soft);
  border-bottom:1px solid var(--line);
}
.banner-slider-track{ display:flex; transition:transform .5s var(--ease); }
.banner-slide{ flex:0 0 100%; min-width:0; line-height:0; }
.banner-slide a{ display:block; }
.banner-slide img{
  display:block; width:100%; height:clamp(180px, 32vw, 420px);
  /* "contain" (not "cover") so a banner always shows in full regardless of the
     source image's own aspect ratio — an admin uploading an existing product
     photo (portrait-ish, lots of whitespace) instead of a purpose-made wide
     1600x500 graphic still gets a clean result instead of a tight, disorienting
     crop. The gradient background above fills the letterboxed space instead of
     flat white, so it doesn't look like a broken/missing image. */
  object-fit:contain; object-position:center;
}
.banner-slider-arrow{
  position:absolute; top:50%; transform:translateY(-50%); width:40px; height:40px; border-radius:99px;
  border:none; background:rgba(1,15,28,.45); color:#fff; font-size:22px; line-height:1;
  display:flex; align-items:center; justify-content:center; cursor:pointer; backdrop-filter:blur(2px);
  transition:background .15s var(--ease); z-index:2;
}
.banner-slider-arrow:hover{ background:rgba(1,15,28,.7); }
.banner-slider-arrow-prev{ left:14px; }
.banner-slider-arrow-next{ right:14px; }
.banner-slider-dots{
  position:absolute; bottom:14px; left:50%; transform:translateX(-50%); display:flex; gap:7px; z-index:2;
}
.banner-slider-dot{
  width:8px; height:8px; border-radius:99px; border:none; background:rgba(255,255,255,.55);
  cursor:pointer; padding:0; transition:background .15s var(--ease), width .15s var(--ease);
}
.banner-slider-dot.is-active{ background:#fff; width:22px; border-radius:99px; }
@media (max-width:575.98px){
  .banner-slider-arrow{ width:32px; height:32px; font-size:18px; }
  .banner-slider-arrow-prev{ left:8px; }
  .banner-slider-arrow-next{ right:8px; }
}

/* ---- Hero ---- */
.hero{
  position:relative; overflow:hidden;
  /* Apple-minimal: flat, calm background — no colored glows. A plain
     alternating light-grey (--paper) field, same as the light sections in
     the apple.com screenshots, replaces the old red/gold radial wash. */
  background:var(--paper);
  padding:96px 0 88px; border-bottom:1px solid var(--line);
}
.hero::before{
  /* Decorative dot-grid texture removed — Apple's light sections are plain
     flat color, no background texture. */
  content:none;
}
.hero .container{ position:relative; }
/* Apple shows small category-context labels as plain uppercase text, not a
   colored pill — see the thin "Mac" / "iPhone" eyebrow labels in the
   reference screenshots, which carry no background fill at all. */
.eyebrow{ font-size:12px; letter-spacing:.07em; text-transform:uppercase; color:var(--muted); font-weight:600; display:inline-flex; align-items:center; gap:7px; margin-bottom:16px; }
.eyebrow::before{ content:none; }
.hero h1{ font-size:clamp(34px,5vw,56px); line-height:1.07; margin-bottom:18px; font-weight:700; letter-spacing:-.02em; }
.hero p{ color:var(--ink-soft); max-width:52ch; font-size:17px; line-height:1.6; margin-bottom:30px; }
/* Floating real-photo cluster behind the hero stat card — see $heroShots in
   home.php. Purely decorative positioning (absolute, anchored to
   .hero-visual-col), hidden below md (.d-none.d-md-block on the cluster
   itself) since there's no room for it once the stat card stacks full-width
   on mobile. */
.hero-visual-col{ position:relative; }
.hero-photo-cluster{ position:absolute; inset:0; pointer-events:none; z-index:1; }
.hero-photo-item{
  position:absolute; border-radius:var(--radius); overflow:hidden; background:var(--surface);
  border:3px solid var(--surface); box-shadow:var(--shadow);
}
.hero-photo-item img{ display:block; width:100%; height:100%; object-fit:contain; background:var(--paper); }
.hero-photo-item-1{ width:88px; height:88px; top:-18px; left:36px; transform:rotate(-6deg); }
.hero-photo-item-2{ width:64px; height:64px; top:-30px; left:150px; transform:rotate(5deg); }
.hero-photo-item-3{ width:58px; height:58px; top:-16px; right:28px; transform:rotate(7deg); }

.hero-stat-card{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-lg); box-shadow:var(--shadow-lg); position:relative; z-index:3; }
.hero-stat-card .row-line{ display:flex; justify-content:space-between; align-items:center; padding:11px 0; border-bottom:1px solid var(--line); font-size:13.5px; color:var(--ink-soft); }
.hero-stat-card .row-line:last-child{ border-bottom:none; }
.hero-stat-card .row-line b{ font-family:var(--font-heading); font-size:17px; color:var(--ink); font-weight:700; }

/* Live-stock pulse readout at the top of the hero stat card */
.hero-stat-pulse{
  display:flex; align-items:center; gap:8px; font-size:13px; font-weight:600; color:var(--ink);
  padding-bottom:14px; margin-bottom:2px; border-bottom:1px solid var(--line);
}
.pulse-dot{ width:8px; height:8px; border-radius:99px; background:var(--ok); flex-shrink:0; position:relative; }
.pulse-dot::after{
  content:''; position:absolute; inset:-4px; border-radius:99px; background:var(--ok); opacity:.4;
  animation:pulse-ring 1.8s ease-out infinite;
}
@keyframes pulse-ring{ 0%{ transform:scale(.6); opacity:.5; } 100%{ transform:scale(2.2); opacity:0; } }

/* "Shop by budget" quick-filter chips in the hero */
.hero-budget-row{ display:flex; align-items:center; gap:9px; flex-wrap:wrap; }
.hero-budget-label{ font-size:12.5px; color:var(--ink-soft); font-weight:600; margin-right:2px; }
.hero-budget-chip{
  font-size:12.5px; font-weight:600; color:var(--ink); background:var(--surface); border:1px solid var(--line-strong);
  border-radius:99px; padding:6px 14px; transition:border-color .15s var(--ease), color .15s var(--ease), background .15s var(--ease), transform .12s var(--ease);
}
.hero-budget-chip:hover{ border-color:var(--brand); color:var(--brand-ink); background:var(--brand-soft); transform:translateY(-1px); }

/* ---- Trust bar (directly under hero) ---- */
.trust-bar{ background:var(--ink); padding:16px 0; }
.trust-bar-row{ display:flex; align-items:center; justify-content:space-between; gap:18px; flex-wrap:wrap; }
.trust-bar-item{ display:flex; align-items:center; gap:9px; color:#f5f5f7; font-size:13px; font-weight:600; white-space:nowrap; }
.trust-bar-icon{ display:flex; color:#9a9a9e; flex-shrink:0; }
.trust-bar-icon svg{ width:18px; height:18px; }
@media (max-width:900px){ .trust-bar-row{ justify-content:flex-start; } }

/* ---- Category tiles v2 (icon-led, homepage "Shop by Category") ----
   .cat-tile-v2 is the card (a plain div, not a link) so it can hold both the
   parent link (.cat-tile-v2-link) AND an always-visible row of child-category
   chips (.cat-tile-subs) underneath — hierarchy shown via a bigger card with
   its children listed directly beneath it, never a click-to-expand accordion
   (this project has repeatedly rejected collapsible category UI). Categories
   with no qualifying children just render the link with nothing below it,
   same look as before this change. */
.cat-tile-v2{
  display:flex; flex-direction:column; gap:8px; background:var(--paper); border:1px solid transparent;
  border-radius:var(--radius); box-shadow:none; padding:24px 20px; height:100%;
  transition:transform .18s var(--ease), background .18s var(--ease);
}
.cat-tile-v2:hover{ transform:translateY(-2px); background:var(--line); }
.cat-tile-v2-link{ display:flex; flex-direction:column; gap:8px; }
.cat-tile-subs{ margin-top:2px; padding-top:12px; border-top:1px solid var(--line-strong); }
.cat-tile-v2-icon,
.cat-tile-icon{
  display:flex; align-items:center; justify-content:center; width:44px; height:44px; border-radius:12px;
  background:var(--surface); color:var(--ink); flex-shrink:0;
  transition:background .18s, color .18s;
}
.cat-tile-icon svg{ width:22px; height:22px; }
.cat-tile-v2:hover .cat-tile-icon{ background:var(--surface); color:var(--brand); }
/* Real sourced category photo (categories.image_url) instead of the generic SVG glyph above —
   same "real image if present, tinted icon badge otherwise" fallback already used for brand tiles/
   logos. Kept the same 44x44 footprint as .cat-tile-icon but dropped the tinted-badge background
   (a photo doesn't read well tinted) and used object-fit:contain like .brand-tile-logo so a
   non-square sourced photo never stretches or crops awkwardly. */
.cat-tile-icon-img{ background:none; padding:0; overflow:hidden; }
.cat-tile-icon-img img{ width:100%; height:100%; object-fit:contain; display:block; border-radius:8px; }
.cat-tile-v2:hover .cat-tile-icon-img{ background:none; }

/* Category listing page header image (templates/category.php) — same sourced
   categories.image_url, shown next to the <h2> when present. Small fixed box +
   object-fit:contain, same treatment as .brand-tile-logo/.cat-tile-icon-img so
   a non-square photo never stretches. */
.cat-header-image{ width:48px; height:48px; object-fit:contain; border-radius:8px; border:1px solid var(--line); background:#fff; flex-shrink:0; }
.cat-tile-v2 h3{ margin:2px 0 0; font-size:15px; color:var(--ink); transition:color .15s; font-weight:600; }
.cat-tile-v2:hover h3{ color:var(--ink); }
.cat-tile-count{ font-size:12.5px; color:var(--muted); }

/* ---- Accent-color rotation utility — RETIRED (2026-09-20 Apple-minimal
   pass). The bold-local pass used this to color-cycle tile/badge/avatar
   accents per index; Apple's reference design uses no per-tile color
   cycling at all (plain white/light-grey cards throughout "Explore the
   lineup" style sections). Markup in home.php/testimonials.php/store-info.php
   still applies these classes (accent_class() helper, $avatarAccents array)
   so they're kept defined here rather than ripped out of every template,
   but every variant now resolves to the exact same neutral values — so
   whichever class lands on a tile, it renders identically, i.e. no visible
   cycling. This is the surgical "restyle, don't delete the plumbing" approach:
   the underlying feature (deterministic per-item accent selection) still
   runs, it's just no longer visually expressed as color. ---- */
.accent-red, .accent-teal, .accent-green, .accent-maroon{
  --tile-accent:var(--ink); --tile-accent-soft:var(--paper);
}

/* ---- Shop by Need tiles (homepage "Shop by Need") ---- */
.usecase-band{ background:var(--surface); }
.usecase-tile{
  display:flex; flex-direction:column; gap:6px; background:var(--paper); border:1px solid transparent;
  border-radius:var(--radius); box-shadow:none; padding:26px 24px; height:100%;
  transition:transform .18s var(--ease), background .18s var(--ease);
}
.usecase-tile:hover{ transform:translateY(-2px); background:var(--line); }
.usecase-tile-icon{
  display:flex; align-items:center; justify-content:center; width:46px; height:46px; border-radius:12px;
  background:var(--surface); color:var(--ink); flex-shrink:0; margin-bottom:4px;
  transition:background .18s, color .18s;
}
.usecase-tile-icon svg{ width:24px; height:24px; }
.usecase-tile:hover .usecase-tile-icon{ background:var(--surface); color:var(--brand); }
.usecase-tile h3{ margin:0; font-size:17px; color:var(--ink); transition:color .15s; font-weight:600; }
.usecase-tile p{ margin:0; font-size:14px; color:var(--ink-soft); flex-grow:1; }
.usecase-tile-cta{ font-size:13px; font-weight:600; color:var(--brand); margin-top:4px; }

/* ---- Shop by Price band (homepage price-band merchandising) ---- */
.price-band-section{ background:var(--surface); border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.price-band-tile{
  display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; gap:2px;
  background:var(--paper); border:1px solid transparent; border-radius:var(--radius); padding:30px 12px; height:100%;
  transition:transform .18s var(--ease), background .18s var(--ease);
}
.price-band-tile:hover{ transform:translateY(-2px); background:var(--line); }
.price-band-tile-count{ font-family:var(--font-heading); font-size:32px; font-weight:700; color:var(--ink); line-height:1; }
.price-band-tile-label{ font-size:11.5px; color:var(--muted); text-transform:uppercase; letter-spacing:.04em; margin-bottom:6px; }
.price-band-tile-range{ font-size:14px; font-weight:500; color:var(--ink-soft); }

/* ---- Recently Viewed rail (Amazon-style, homepage — real per-visitor cookie, see track_recently_viewed()) ---- */
.recently-viewed-band{ background:var(--paper); }

/* ---- Horizontal product carousel (homepage "Recently Listed" / "Best Deals") ---- */
.product-carousel{
  display:flex; gap:16px; overflow-x:auto; scroll-snap-type:x proximity; padding-bottom:6px;
  scrollbar-width:thin;
}
/* Card width sized so ~4 cards are visible per row/viewport on desktop —
   these homepage carousels never sit beside a sidebar (full-width section),
   matching the "no sidebar = 4-up, sidebar present = 3-up" rule applied to
   the category/brand/finder-results grids below. */
.product-carousel-item{ flex:0 0 minmax(220px, calc((100% - 48px) / 4)); scroll-snap-align:start; }
@media (max-width:991.98px){ .product-carousel-item{ flex-basis:calc((100% - 16px) / 2); } }
@media (max-width:575.98px){ .product-carousel-item{ flex-basis:80vw; } }

/* ---- Product grid density (Apple-minimal, 2026-09-20) ----
   REVERSES the previous bold-local pass, which tightened gutters and forced
   a 5-up column on wide desktop for a dense marketplace-listing feel.
   Apple's own "Explore the lineup" reference sections show 3-4 large cards
   per row with generous gutters, never a dense 5+ grid — per explicit
   correction, this site locks to exactly 3 per row at desktop width
   everywhere multiple product cards render as a grid (category/brand/
   finder-results listing pages via .col-lg-4 in their templates; see
   category.php, product.php related-products, finder-results.php,
   brand.php). Gutters are intentionally left at Bootstrap's default g-3
   (1rem/16px) — no gutter-tightening override — for the calmer, airier
   spacing the reference calls for. */
.carousel-nav{ display:flex; gap:6px; flex-shrink:0; }
.carousel-arrow{
  width:34px; height:34px; border-radius:99px; border:1px solid var(--line-strong); background:var(--surface);
  color:var(--ink); font-size:18px; line-height:1; display:flex; align-items:center; justify-content:center;
  cursor:pointer; transition:border-color .15s, color .15s, background .15s;
}
.carousel-arrow:hover{ border-color:var(--brand); color:var(--brand-ink); background:var(--brand-soft); }

.deals-band{ background:var(--paper); }
/* "Today's Best Deals" eyebrow — plain understated text like every other
   .eyebrow, no colored fill/shadow. Real urgency here comes from the actual
   discounted prices in the cards below, not from badge styling. */
.brand-band{ background:var(--surface); }

/* ---- How It Works (homepage) ---- */
.how-it-works{ background:var(--surface); border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
.section-sub{ color:var(--ink-soft); max-width:52ch; font-size:15px; margin:6px 0 0; }
.how-step{ position:relative; text-align:center; padding:0 12px; }
.how-step-connector{
  position:absolute; top:32px; left:calc(50% + 46px); right:calc(-50% + 46px); height:2px;
  background:repeating-linear-gradient(90deg, var(--line-strong) 0 8px, transparent 8px 16px);
}
.how-step-icon{
  position:relative; width:64px; height:64px; margin:0 auto 16px; border-radius:50%;
  background:var(--brand-soft); color:var(--brand); display:flex; align-items:center; justify-content:center;
}
.how-step-icon svg{ width:28px; height:28px; }
.how-step-n{
  position:absolute; bottom:-4px; right:-4px; width:22px; height:22px; border-radius:99px; background:var(--brand);
  color:#fff; font-size:11px; font-weight:700; display:flex; align-items:center; justify-content:center; box-shadow:0 0 0 3px var(--surface);
}
.how-step h4{ font-size:16px; margin-bottom:6px; }
.how-step p{ font-size:13.5px; color:var(--ink-soft); max-width:32ch; margin:0 auto; }

/* Buttons — Apple's pill shape: fully rounded, flat solid blue primary, thin
   dark/plain outline for secondary. No gradients, no colored shadows; the
   only shadow is a very subtle hover darken. WhatsApp CTAs keep WhatsApp's
   own green per the explicit exception in the brief (real user convention,
   not part of the site's own color system). */
.btn{ display:inline-flex; align-items:center; gap:8px; font-weight:500; border-radius:99px; padding:11px 22px; font-size:14.5px; transition:transform .12s var(--ease), background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease); }
.btn:active{ transform:translateY(1px); }
.btn-sm{ padding:7px 16px; font-size:13px; }
.btn-primary{ background:var(--brand); border-color:var(--brand); color:#fff; box-shadow:none; }
.btn-primary:hover, .btn-primary:focus{ background:var(--brand-ink); border-color:var(--brand-ink); color:#fff; }
.btn-outline-primary{ color:var(--ink); border:1px solid var(--line-strong); background:transparent; }
.btn-outline-primary:hover{ background:var(--ink); border-color:var(--ink); color:#fff; }
.btn-wa{ background:#25D366; color:#fff; border-color:#25D366; border-radius:99px; box-shadow:none; }
.btn-wa:hover{ background:#1eb955; border-color:#1eb955; color:#fff; }
.btn-add-cart{ padding:7px 15px; font-size:12px; }

/* ---- Section scaffolding ---- */
.block-head a{ font-size:14px; color:var(--brand); font-weight:400; transition:color .15s; }
.block-head a:hover{ color:var(--brand-ink); }

/* ---- Category tiles / brand tiles / testimonials / store info: shared card look ----
   Apple-minimal: flat light-grey card, no border, no shadow, no per-tile
   accent color — a subtle background darken on hover is the only feedback,
   matching the plain promo-panel cards on apple.com/mac ("Explore the lineup"). */
.cat-tile, .brand-tile, .testimonial-card, .store-info-card{
  background:var(--paper); border:1px solid transparent; border-radius:var(--radius); box-shadow:none; height:100%;
  transition:transform .18s var(--ease), background .18s var(--ease);
}
.cat-tile:hover, .brand-tile:hover{ transform:translateY(-2px); background:var(--line); }
.cat-tile span, .brand-tile span{ font-size:12.5px; color:var(--muted); }
.cat-tile h3{ transition:color .15s; font-weight:600; }
.brand-tile .mark{ font-family:var(--font-heading); font-size:18px; font-weight:600; color:var(--ink); background:none; padding:0; }
.brand-tile-badge{
  display:flex; align-items:center; justify-content:center; width:34px; height:34px; margin:0 auto 8px; border-radius:99px;
  background:var(--surface); color:var(--ink);
  font-family:var(--font-heading); font-weight:600; font-size:14px; transition:background .18s, color .18s;
}
.brand-tile:hover .brand-tile-badge{ background:var(--surface); color:var(--brand); }
/* Real attached logo (categories.image_url) in place of the initial-letter badge —
   fixed box + object-fit:contain so a tall/wide/non-square source logo never
   stretches or breaks the tile's card layout, same treatment as product images. */
.brand-tile-logo{ display:block; width:100%; height:34px; margin:0 auto 8px; object-fit:contain; }

/* ---- Product card ---- */
/* ---- Product card (tp-product-item-2 family) ----
   Matches the real supertechsys.com category page's product card exactly —
   same class names, same layout, not a generic redesign. */
.tp-product-item-2{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); overflow:hidden;
  transition:transform .22s var(--ease), box-shadow .22s var(--ease);
  display:flex; flex-direction:column; height:100%; position:relative;
}
.tp-product-item-2:hover{ transform:translateY(-2px); box-shadow:var(--shadow); }

/* "Save Rs. X" — kept as a real-data-only note (no fabricated urgency), but
   given a small filled tag treatment instead of plain text so the genuine
   savings actually catch the eye on a scan of the grid, matching the bolder
   price treatment below. Still just one savings cue, never doubled up with
   a separate percent ribbon. */
.you-save{
  display:inline-flex; align-items:center; color:var(--brand); font-size:11.5px; font-weight:700;
  margin:0; background:var(--brand-soft); padding:3px 8px; box-shadow:none; border-radius:99px;
  letter-spacing:.01em;
}

.tp-product-thumb-2{ background:var(--paper); border-bottom:1px solid var(--line); overflow:hidden; flex-shrink:0; }
.tp-product-thumb-2 a{ display:flex; align-items:center; justify-content:center; }
.tp-product-thumb-2 img{
  width:100%; height:200px; object-fit:contain; object-position:center; display:block;
  transition:transform .35s var(--ease); padding:10px; background:var(--paper);
}
.tp-product-item-2:hover .tp-product-thumb-2 img{ transform:scale(1.04); }
.tp-product-thumb-2 svg{ height:200px; width:auto; padding:10px; color:var(--line-strong); }

.tp-product-content-2{ padding:12px 12px 14px; display:flex; flex-direction:column; flex:1; }

.tp-product-title-2{ font-size:13.5px; font-weight:600; line-height:1.4; margin:0 0 6px; color:var(--ink); }
.tp-product-title-2 a{
  color:var(--ink); text-decoration:none; transition:color .2s;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.tp-product-title-2 a:hover{ color:var(--brand); }

.tp-product-price-wrapper-2{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; margin-bottom:4px; }
/* Bolder price treatment: the current/sale price is now the clear visual
   anchor of the card (larger, heavier, brand blue) so a discount actually
   reads at a glance — old price stays a plain muted strikethrough right
   next to it for contrast. Still restrained: one accent color, no gradients
   or shadows, consistent with the rest of the Apple-minimal system. */
.tp-product-price-2.new-price{ font-size:19px; font-weight:800; color:var(--brand); letter-spacing:-.01em; }
.tp-product-price-2.old-price{ font-size:12.5px; font-weight:400; color:var(--muted); text-decoration:line-through; }
/* Regular (non-sale) card pricing — price_html()'s .now/.was fallback, used
   whenever a product has no active discount. Matches the sale-price pair
   above (same size/weight/color) so every card's price reads with the same
   visual weight regardless of whether that specific product is on sale. */
.tp-product-price-wrapper-2 .now.price{ font-size:19px; font-weight:800; color:var(--brand); letter-spacing:-.01em; }
.tp-product-price-wrapper-2 .was.price{ font-size:12.5px; font-weight:400; color:var(--muted); text-decoration:line-through; }
.call-for-price{ color:var(--brand) !important; font-size:14px !important; font-weight:500; }
.pd-price .call-for-price{ font-size:22px !important; }
/* Plain-text "Save Rs. X" note, shown right after the price in the same row
   (moved out of the old absolute corner-flag position — see .you-save
   above). */
.tp-product-price-wrapper-2 .you-save{ order:3; flex-basis:100%; margin-top:1px; }

/* Spec attribute rows (CPU/Cache/Screen/RAM/GPU with icons) — quieted from a
   bordered/left-accented "chip" look to plain thin-divider rows, matching
   Apple's plain tech-spec lists (label in muted grey, value in body color,
   a hairline divider, no colored border/background). */
.product-attributes-list{ list-style:none; padding:0; margin:8px 0 0; display:flex; flex-direction:column; }
.product-attributes-list li{
  display:flex; align-items:center; gap:9px; padding:6px 0;
  border-bottom:1px solid var(--line); border-radius:0; overflow:hidden;
}
.product-attributes-list li:last-child{ border-bottom:none; }
.attr-icon{ flex-shrink:0; width:16px; height:16px; display:flex; align-items:center; justify-content:center; color:var(--muted); }
.attr-icon svg{ width:14px; height:14px; display:block; }
.attr-label{ font-size:10px; font-weight:600; color:var(--muted); text-transform:uppercase; letter-spacing:.05em; white-space:nowrap; flex-shrink:0; min-width:42px; }
.attr-value{ font-size:12.5px; font-weight:500; color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; flex:1; }

/* ---- Product card action row (2026-09-20) ----
   Add to Cart + Compare sit side by side in one row, mirroring Apple's
   paired primary/secondary button layout (e.g. "Buy" + a smaller secondary
   action next to it) rather than two full-width buttons stacked on separate
   lines. Add to Cart is the filled primary pill and takes the remaining
   space (flex:1); Compare is a fixed-width icon+label secondary pill beside
   it. Wherever product_card() renders — homepage carousels, category/brand/
   finder-results grids, recently-viewed rail — gets this row automatically
   since it's the one shared component. */
.tp-product-actions-2{ display:flex; align-items:stretch; gap:8px; margin-top:auto; padding-top:2px; }
.tp-product-content-2 .btn-add-cart{
  flex:1; min-width:0; border-radius:99px; justify-content:center;
  padding:8px 12px; font-size:12.5px; font-weight:500; white-space:nowrap;
}

/* Compare pill button (matches sts-local-compare plugin's real button) —
   restyled as a compact secondary pill that sits next to Add to Cart rather
   than a full-width row above the spec list. */
.sts-compare-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:5px; font-size:12px; font-weight:500; color:var(--ink-soft);
  background:transparent; border:1px solid var(--line-strong); border-radius:99px; padding:8px 12px;
  cursor:pointer; transition:all .2s; flex-shrink:0;
}
.sts-compare-btn:hover{ color:var(--brand); border-color:var(--brand); background:var(--brand-soft); }
.sts-compare-btn.active{ color:#fff; background:var(--brand); border-color:var(--brand); }
.sts-compare-btn svg{ flex-shrink:0; }
/* Compare's text label hides below a certain card width (icon-only,
   aria via visible text still present for larger cards) so the pair never
   wraps or overflows a narrow 3-up card at small breakpoints. */
@media (max-width:400px){
  .sts-compare-btn-label{ display:none; }
  .sts-compare-btn{ padding:8px 10px; }
}

/* ---- Product detail ---- */
.crumbs{ font-size:12.5px; color:var(--muted); }
.crumbs a{ color:var(--ink-soft); transition:color .15s; }
.crumbs a:hover{ color:var(--brand-ink); }

/* Main gallery image: switched from object-fit:cover (which crops laptop
   photos with inconsistent aspect ratios) to contain-with-padding, plus a
   cursor-following zoom on hover (desktop only — no pointer:fine means no
   hover, so touch devices just get the plain image, no dead zoom affordance
   to accidentally trigger). */
.gallery-main{
  aspect-ratio:1; background:var(--paper); border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:none; display:flex; align-items:center; justify-content:center; color:var(--line-strong);
  overflow:hidden; position:relative; padding:16px;
}
.gallery-main img{ object-fit:contain; transition:transform .3s var(--ease, ease); cursor:zoom-in; }
.gallery-main svg{ width:80px; height:80px; }
@media (hover:hover) and (pointer:fine){
  .gallery-main.zoomed img{ transform:scale(1.6); cursor:zoom-out; }
}

.gallery-thumbs{ --thumb-size:76px; }
.gallery-thumb-btn{
  width:var(--thumb-size); height:var(--thumb-size); padding:4px; border-radius:var(--radius-sm) !important;
  border:2px solid var(--line); background:var(--surface); overflow:hidden; cursor:pointer;
  transition:border-color .15s, transform .12s, box-shadow .15s;
}
.gallery-thumb-btn img{ width:100%; height:100%; object-fit:contain; display:block; }
.gallery-thumb-btn:hover{ transform:translateY(-2px); border-color:var(--line-strong); }
.gallery-thumb-btn.active{ border-color:var(--brand); box-shadow:0 0 0 1px var(--brand); }
@media (max-width:480px){ .gallery-thumbs{ --thumb-size:56px; } }

.pd-title{ font-size:clamp(26px,3vw,36px); font-weight:700; letter-spacing:-.02em; }
.pd-meta{ display:flex; flex-wrap:wrap; align-items:center; gap:10px 16px; font-size:13px; color:var(--ink-soft); margin:10px 0 16px; }
.pd-meta-instock{ color:var(--ok); font-weight:600; }
.pd-meta-outstock{ color:var(--danger); font-weight:600; }
.pd-price .now{ font-family:var(--font-heading); font-size:36px; font-weight:800; color:var(--brand); letter-spacing:-.01em; }
.pd-price .was{ text-decoration:line-through; color:var(--muted); font-size:16px; font-weight:400; }
/* Real Rs. amount saved next to the PDP price — a small filled pill tag,
   matching the same "Save Rs. X" treatment used on product cards
   (.you-save in style.css) so the savings cue reads consistently across
   the site instead of a separate percent-based convention on this page. */
.pd-discount-badge{
  display:inline-flex; align-items:center; gap:5px; background:var(--brand-soft);
  color:var(--brand); font-weight:700; font-size:13px; padding:5px 10px; border-radius:99px; line-height:1.3;
  box-shadow:none;
}

/* Buy box: groups price/glance/variants/CTAs/trust chips into one visually
   distinct card so the whole purchase decision reads as a single unit
   instead of loose stacked rows down the column — same idea as a typical
   e-commerce PDP's right-column "buy box", adapted to this site's plain
   Apple-minimal card language (hairline border, no shadow). */
.pd-buybox{ border:1px solid var(--line); border-radius:var(--radius); padding:20px 22px; background:var(--surface); }
.pd-buybox .cta-row{ margin-top:2px; }
.pd-buybox .btn-wa{ flex:1 1 auto; min-width:180px; justify-content:center; font-weight:600; }
.pd-buybox .cta-row .btn-outline-primary{ display:inline-flex; align-items:center; gap:6px; }
.trust-chip{ font-size:12px; background:var(--paper); color:var(--ink-soft); font-weight:500; padding:7px 13px; border:1px solid var(--line); }

/* Section labels above "At a Glance" / "Full Specifications" — plain small
   uppercase eyebrow text, matching this theme's existing .block-head/
   .pf-spec-group h5 convention rather than introducing a new heading style. */
.pd-section-label{ font-size:12px; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); font-weight:600; margin-bottom:12px; }

/* ---- "At a Glance" quick-spec strip (laptopmedia.com-inspired) ----
   A row of icon+label+value tiles above the full spec-group tables, giving
   a scannable summary before the detailed breakdown. Reuses the same plain
   hairline-divider aesthetic as .product-attributes-list / .spec-group
   rather than colored badges, to stay consistent with the Apple-minimal
   palette (see :root comment at the top of this file). */
.pd-glance{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(190px, 1fr));
  gap:1px; background:var(--line); border:1px solid var(--line); border-radius:var(--radius);
  overflow:hidden;
}
.glance-item{ display:flex; align-items:center; gap:12px; background:var(--surface); padding:14px 16px; }
.glance-icon{ flex-shrink:0; width:34px; height:34px; border-radius:50%; background:var(--paper); color:var(--ink-soft); display:flex; align-items:center; justify-content:center; }
.glance-icon svg{ width:18px; height:18px; display:block; }
.glance-text{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.glance-label{ font-size:11px; font-weight:600; color:var(--muted); text-transform:uppercase; letter-spacing:.04em; }
/* Values wrap onto a 2nd line rather than truncate — "Core i5 7th
   Generation"/"Intel Integrated Graphics" are common real values here and
   were getting cut to "Core i5 7th Genera…" at the original single-line
   150px column width (caught by screenshot, not by an automated check —
   the ellipsis rendered "successfully," it just hid real data). */
.glance-value{ font-size:13.5px; font-weight:600; color:var(--ink); line-height:1.3; white-space:normal; word-break:break-word; }

.spec-group{ background:var(--paper); border:1px solid transparent; border-radius:var(--radius); box-shadow:none; padding:20px 22px; height:100%; }
.spec-group h5{ display:flex; align-items:center; gap:8px; font-size:12px; letter-spacing:.04em; text-transform:uppercase; color:var(--ink); font-weight:600; margin-bottom:12px; }
.spec-group-icon{ flex-shrink:0; width:20px; height:20px; display:flex; align-items:center; justify-content:center; color:var(--brand); }
.spec-group-icon svg{ width:16px; height:16px; display:block; }
.spec-row{ display:flex; justify-content:space-between; gap:12px; font-size:13.5px; padding:8px 0; border-bottom:1px solid var(--line); }
.spec-row:last-child{ border-bottom:none; }
.spec-row dt{ color:var(--muted); margin:0; }
.spec-row dd{ margin:0; font-weight:500; text-align:right; color:var(--ink); }
@media (max-width:480px){
  .pd-glance{ grid-template-columns:repeat(auto-fit, minmax(130px, 1fr)); }
  .glance-item{ padding:12px; gap:10px; }
  .glance-icon{ width:30px; height:30px; }
}

/* Description: real paragraph rhythm instead of one nl2br'd text wall —
   see product_description_html() in partials/product-card-fn.php for how
   the source text is split into <p>/<h3> blocks. */
.pd-description{ max-width:75ch; font-size:14.5px; line-height:1.7; color:var(--ink-soft); }
.pd-description p{ margin:0 0 14px; }
.pd-description p:last-child{ margin-bottom:0; }
.pd-desc-subhead{ font-size:16px; font-weight:700; color:var(--ink); margin:20px 0 8px; }
.pd-desc-subhead:first-child{ margin-top:0; }

/* Full Specifications wrapper: a subtle top divider ties it visually to the
   "At a Glance"/description content above it instead of floating as an
   unrelated block once description-trimming (see above) shortened the gap
   between them. */
.pd-fullspecs-wrap{ padding-top:24px; border-top:1px solid var(--line); }

/* ---- Finder ---- */
.finder-hero{
  background:var(--paper);
  padding:64px 0 48px; border-bottom:1px solid var(--line);
}
.finder-hero h1{ font-size:30px; max-width:18ch; }
.finder-hero p{ color:var(--ink-soft); max-width:56ch; }

/* Section panel per group (General/Processor/Display/...) — always expanded, not collapsible (confirmed user preference) */
.finder-section{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow-xs); }
.finder-section-head{ display:flex; align-items:center; gap:12px; padding:16px 20px 4px; }
.finder-section-icon{ display:flex; color:var(--brand-ink); flex-shrink:0; }
.finder-section-icon svg{ width:19px; height:19px; }
.finder-section-name{ flex:1; font-size:14.5px; font-weight:700; color:var(--ink); }
.finder-section-badge{ background:var(--brand); color:#fff; font-size:11.5px; font-weight:700; border-radius:99px; padding:2px 9px; flex-shrink:0; }
.finder-section-body-inner{ padding:16px 20px 20px; display:flex; flex-direction:column; gap:14px; }

.finder-card{ background:var(--paper); border:1px solid var(--line); border-radius:10px; padding:16px 18px; }
.finder-card-head{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-bottom:14px; }
.finder-card-head h3{ font-size:13px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); margin:0; }
.finder-field-count{ font-size:12px; font-weight:700; color:var(--brand-ink); }

.finder-fields-loading{ display:grid; gap:16px; }
.finder-skel{ height:96px; border-radius:12px; background:linear-gradient(90deg, var(--surface) 25%, var(--line) 37%, var(--surface) 63%); background-size:400% 100%; animation:finder-shimmer 1.4s ease infinite; border:1px solid var(--line); }
@keyframes finder-shimmer{ 0%{ background-position:100% 0; } 100%{ background-position:0 0; } }

/* Chip multi-select — no Bootstrap equivalent, kept custom */
.chip-row{ display:flex; flex-wrap:wrap; gap:8px; }
.chip{ display:inline-flex; align-items:center; gap:6px; border:1px solid var(--line-strong); background:var(--paper); border-radius:99px; padding:7px 8px 7px 14px; font-size:13px; cursor:pointer; user-select:none; transition:border-color .15s, background .15s, color .15s, transform .1s; }
.chip:hover{ border-color:var(--brand); transform:translateY(-1px); }
.chip input{ display:none; }
.chip.active{ background:var(--brand); border-color:var(--brand); color:#fff; }
.chip .chip-text{ max-width:220px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.chip .chip-count{ font-size:11px; color:var(--muted); background:var(--surface); border-radius:99px; padding:1px 6px; min-width:18px; text-align:center; flex-shrink:0; }
.chip.active .chip-count{ background:rgba(255,255,255,.25); color:#fff; }

.finder-field-search{ margin-bottom:12px; }

/* Dual-thumb price slider — no Bootstrap equivalent, kept custom */
.finder-price-readout{ font-family:var(--font-heading); font-weight:700; font-size:16px; color:var(--brand-ink); }
.price-slider{ position:relative; height:20px; margin:6px 4px 18px; }
.price-slider-track{ position:absolute; top:50%; left:0; right:0; height:4px; background:var(--line-strong); border-radius:99px; transform:translateY(-50%); }
.price-slider-range{ position:absolute; top:50%; height:4px; background:var(--brand); border-radius:99px; transform:translateY(-50%); }
.price-range{ position:absolute; top:0; left:0; width:100%; margin:0; appearance:none; background:none; pointer-events:none; height:20px; }
.price-range::-webkit-slider-thumb{ appearance:none; pointer-events:auto; width:18px; height:18px; border-radius:50%; background:#fff; border:2px solid var(--brand); box-shadow:0 1px 3px rgba(0,0,0,.25); cursor:pointer; margin-top:0; }
.price-range::-moz-range-thumb{ pointer-events:auto; width:18px; height:18px; border-radius:50%; background:#fff; border:2px solid var(--brand); box-shadow:0 1px 3px rgba(0,0,0,.25); cursor:pointer; }
.price-range::-webkit-slider-runnable-track{ background:transparent; }
.price-range::-moz-range-track{ background:transparent; }
.range-input{ position:relative; }
.range-input span{ position:absolute; left:10px; top:50%; transform:translateY(-50%); font-size:12.5px; color:var(--muted); pointer-events:none; }
.range-input input[type=number]{ padding-left:34px; }

/* Sticky summary sidebar (Bootstrap .sticky-lg-top handles the position; this keeps the card look) */
.finder-summary-card{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-lg); padding:26px; box-shadow:var(--shadow); }
.finder-match-count{ text-align:center; padding-bottom:18px; border-bottom:1px solid var(--line); margin-bottom:16px; }
.finder-match-count .n{ display:block; font-family:var(--font-heading); font-weight:700; font-size:36px; color:var(--brand-ink); line-height:1.1; }
.finder-match-count .label{ display:block; font-size:13px; color:var(--muted); margin-top:2px; }
.finder-active-filters{ display:flex; flex-wrap:wrap; gap:6px; margin-bottom:16px; min-height:0; }
.finder-active-filters:empty{ margin-bottom:0; }
.active-filter-chip{ display:inline-flex; align-items:center; gap:6px; background:var(--brand-soft); color:var(--brand-ink); border-radius:99px; padding:5px 6px 5px 12px; font-size:12px; font-weight:600; }
.active-filter-chip button{ background:none; border:none; color:var(--brand-ink); font-size:15px; line-height:1; cursor:pointer; padding:0 2px; opacity:.7; }
.active-filter-chip button:hover{ opacity:1; }
.finder-summary-hint{ font-size:12px; color:var(--muted); text-align:center; }
.finder-summary-hint a{ color:var(--brand-ink); font-weight:600; }

/* ---- Compare ---- */
table.compare thead th{ background:var(--paper); position:sticky; top:0; }
table.compare .attr-label{ color:var(--muted); white-space:nowrap; font-weight:600; }
.compare-thumb{ display:block; width:96px; height:96px; margin:0 0 10px; border-radius:var(--radius); overflow:hidden; background:var(--surface); }
.compare-thumb img{ width:100%; height:100%; object-fit:contain; }
/* Section-heading rows (General/Processor/Display/...) bucketing the spec
   rows below them — same grouping + icon language as .spec-group on the
   product page's "Full Specifications" card grid, adapted to a table row
   since compare is tabular, not card-based. */
table.compare .compare-group-row th{
  background:var(--paper); position:sticky; top:37px;
  text-align:left; font-size:12px; letter-spacing:.04em; text-transform:uppercase;
  color:var(--ink); font-weight:600; padding:10px 12px;
}
table.compare .compare-group-icon{ display:inline-flex; align-items:center; justify-content:center; width:16px; height:16px; color:var(--brand); margin-right:8px; vertical-align:-3px; }
table.compare .compare-group-icon svg{ width:14px; height:14px; display:block; }
/* "Highlight differences"/"Highlight similarities" row tints (compare-view
   toggle) — reuses the existing --danger/--brand semantic tokens rather than
   inventing new colors, so this stays visually consistent with the rest of
   the site's palette. Every row stays visible at all times; only the
   background/left-edge accent changes. */
table.compare tr.row-highlight-diff td,
table.compare tr.row-highlight-diff td.attr-label{ background:var(--danger-bg); box-shadow:inset 3px 0 0 var(--danger); }
table.compare tr.row-highlight-same td,
table.compare tr.row-highlight-same td.attr-label{ background:var(--brand-soft); box-shadow:inset 3px 0 0 var(--brand); }
.compare-view-toggle .btn.active{ color:#fff; background:var(--brand); border-color:var(--brand); }

/* ---- Cart ---- */
.cart-items{ display:flex; flex-direction:column; gap:1px; background:var(--line); border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow-xs); }
.cart-row{ display:grid; grid-template-columns:64px 1fr auto auto auto; align-items:center; gap:14px; background:var(--surface); padding:12px 16px; }
.cart-thumb{ width:56px; height:56px; border-radius:6px; overflow:hidden; background:var(--paper); flex-shrink:0; }
.cart-thumb img{ width:100%; height:100%; object-fit:cover; }
.cart-info{ display:flex; flex-direction:column; gap:3px; min-width:0; }
.cart-title{ font-weight:600; font-size:14px; }
.cart-unit-price{ font-size:12px; color:var(--muted); }
.cart-qty{ display:flex; align-items:center; gap:8px; }
.qty-btn{ width:26px; height:26px; border-radius:6px; border:1px solid var(--line-strong); background:var(--surface); cursor:pointer; font-size:15px; line-height:1; display:flex; align-items:center; justify-content:center; }
.qty-btn:hover{ border-color:var(--brand); color:var(--brand-ink); }
.qty-val{ min-width:18px; text-align:center; font-weight:600; font-size:13.5px; }
.cart-line-total{ font-weight:700; color:var(--brand-ink); font-size:14px; white-space:nowrap; }
.cart-remove{ background:none; border:none; color:var(--muted); cursor:pointer; font-size:14px; padding:4px; }
.cart-remove:hover{ color:var(--danger); }
.cart-summary{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:20px; box-shadow:var(--shadow); }
.cart-summary-row{ display:flex; justify-content:space-between; font-size:13.5px; padding:6px 0; }
.cart-summary-total{ font-weight:700; font-size:16px; border-top:1px solid var(--line); margin-top:4px; padding-top:12px; }
@media (max-width:640px){
  .cart-row{ grid-template-columns:48px 1fr; grid-template-areas:"thumb info" "qty qty" "total remove"; row-gap:8px; }
  .cart-thumb{ grid-area:thumb; width:48px; height:48px; }
  .cart-info{ grid-area:info; }
  .cart-qty{ grid-area:qty; }
  .cart-line-total{ grid-area:total; }
  .cart-remove{ grid-area:remove; justify-self:end; }
}

/* ---- Admin-only (out of scope for the Bootstrap conversion; kept as-is) ---- */
.form-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:14px; }
.form-grid label{ font-size:12.5px; font-weight:700; color:var(--ink-soft); display:block; margin-bottom:5px; }
.form-grid input, .form-grid select, .form-grid textarea{
  width:100%; padding:8px 11px; border:1px solid var(--line-strong); border-radius:6px; font-family:inherit; font-size:13.5px; background:var(--surface);
}
.form-full{ grid-column:1 / -1; }
.admin-bar{ background:var(--ink); color:#e7e9ec; padding:10px 0; font-size:13px; }
.admin-bar .wrap{ display:flex; justify-content:space-between; max-width:1180px; margin:0 auto; padding:0 22px; }
.admin-bar a{ color:#e7e9ec; }
.admin-table{ width:100%; border-collapse:collapse; background:var(--surface); border:1px solid var(--line); border-radius:8px; overflow:hidden; }
.admin-table th, .admin-table td{ padding:10px 14px; border-bottom:1px solid var(--line); font-size:13px; text-align:left; }
.admin-table thead th{ background:var(--paper); font-size:11.5px; text-transform:uppercase; letter-spacing:.04em; color:var(--muted); }
.pill-status{ font-size:11px; padding:2px 8px; border-radius:99px; font-weight:700; }
.pill-status.instock{ background:var(--ok-bg); color:var(--ok); }
.pill-status.outofstock{ background:var(--danger-bg); color:var(--danger); }
.wrap{ max-width:1180px; margin:0 auto; padding:0 22px; }

/* ---- Footer ---- */
footer.site{ background:var(--ink); color:#c7cad0; margin-top:48px; padding:44px 0 26px; font-size:13px; }
footer.site h5{ color:#fff; font-family:var(--font-heading); font-size:15px; margin-bottom:12px; }
footer.site a{ color:#c7cad0; display:block; padding:4px 0; transition:color .15s; }
footer.site a:hover{ color:var(--brand-2); }
.footer-address{ max-width:26ch; color:#9aa0a8; line-height:1.6; }
.foot-bottom{ text-align:center; padding-top:22px; margin-top:26px; border-top:1px solid rgba(255,255,255,.1); color:#83888f; font-size:12px; }

.empty-state{ text-align:center; padding:60px 20px; color:var(--muted); background:var(--surface); border:1px dashed var(--line-strong); border-radius:var(--radius); }
.listing-toolbar .count{ font-weight:600; color:var(--ink-soft); font-size:13.5px; }
.listing-toolbar .form-select{ border-radius:var(--radius-sm); }

/* ---- Pagination (Bootstrap .pagination handles structure; brand the active/current state) ---- */
.pagination .page-link{ color:var(--ink); border-radius:var(--radius-sm); margin:0 2px; border-color:var(--line); transition:border-color .15s, color .15s, background .15s; }
.pagination .page-item.active .page-link{ background:var(--brand); border-color:var(--brand); box-shadow:var(--shadow-xs); }
.pagination .page-link:hover{ color:var(--brand-ink); border-color:var(--brand); }

/* ---- Subcategory chips (category page) ---- */
.subcat-row a{ font-size:12.5px; }
.subcat-row a:hover{ border-color:var(--brand); color:var(--brand-ink); }

/* ---- Category page filter sidebar ----
   Sticks below the site header (not at the bare viewport top) — the header
   itself is position:sticky with z-index:1040, higher than Bootstrap's
   .sticky-lg-top default (1030) on this sidebar, so the header always paints
   over it during scroll instead of the reverse.

   Two different custom properties on purpose, both synced live by app.js
   ("Header height sync"):
   --header-h      — the header's *expanded/resting* height, frozen while
                      .header-hide-top is active. Only ever used by body's
                      padding-top (>=992px media query above) — body is
                      normal document flow and must always reserve space for
                      the header's largest state, or the page would jump
                      every time the header collapses/expands.
   --header-h-live — the header's *actual current* height, updated every
                      scroll frame including mid-collapse. Used here, since
                      this sidebar's sticky top offset and max-height need to
                      track where the header really is right now, not where
                      it is at rest.
   Both start at the same 122px pre-JS/no-JS fallback below (first paint,
   before app.js has run) — app.js overwrites each with its real measured
   value once it runs, since a hand-guessed constant drifts the moment the
   header's content changes height.

   History: originally a single --header-h fixed a real bug (2026-09-25:
   header grew to 158px, this constant stayed at 122px, so the fixed header
   overlapped/clipped the page's first ~36px of content — the breadcrumb nav
   took the hit since it's first in page flow). That fix then caused a
   second, opposite bug reported right after: once --header-h was pinned to
   the correct *expanded* 158px and never moved (deliberately, to stop
   collapse-animation jitter — see app.js), this sidebar's `top:calc(
   var(--header-h) + 16px)` stayed pinned as if the header were still 158px
   tall even after scrolling collapsed it to ~47px, leaving a ~110px dead gap
   above the sidebar (and the product grid) for as long as the page stayed
   scrolled. One variable can't correctly serve both "how much space must
   always be reserved" and "how tall is the header right now" — hence the
   split. Don't collapse these back into one property without re-solving
   both bugs at once. */
:root{ --header-h: 122px; --header-h-live: 122px; }
.cat-filters{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow-xs);
  max-height:calc(100vh - var(--header-h-live) - 16px); display:flex; flex-direction:column; overflow:hidden;
  transition:top .25s var(--ease), max-height .25s var(--ease);
}
#cat-filter-form{ display:flex; flex-direction:column; flex:1; min-height:0; }
.cat-filters-scroll{ overflow-y:auto; padding:16px; flex:1; min-height:0; }
.cat-filters-head{ flex-shrink:0; padding:16px 16px 0; display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:10px; }
.cat-filters-head h3{ font-size:14px; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--ink); margin:0; }

.cat-filter-section{ border-top:1px solid var(--line); padding:12px 0; }
.cat-filter-section:first-of-type{ border-top:none; padding-top:6px; }
.cat-filter-section summary{
  display:flex; align-items:center; gap:8px; cursor:pointer; list-style:none;
  font-size:13.5px; font-weight:700; color:var(--ink); padding:2px 0;
}
.cat-filter-section summary::-webkit-details-marker{ display:none; }
.cat-filter-section summary::before{
  content:''; width:8px; height:8px; border-right:2px solid var(--ink-soft); border-bottom:2px solid var(--ink-soft);
  transform:rotate(-45deg); transition:transform .15s; flex-shrink:0; margin-left:2px;
}
.cat-filter-section[open] summary::before{ transform:rotate(45deg); }
.cat-filter-section-name{ flex:1; }
.cat-filter-section-body{ padding-top:10px; display:flex; flex-direction:column; gap:14px; }

.cat-filter-attr-label{ font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--ink-soft); margin-bottom:6px; }
.cat-filter-checklist{ display:flex; flex-direction:column; gap:2px; max-height:180px; overflow-y:auto; }
.cat-filter-check{ display:flex; align-items:center; gap:8px; font-size:13px; padding:5px 4px; border-radius:6px; cursor:pointer; user-select:none; }
.cat-filter-check:hover{ background:var(--paper); }
.cat-filter-check.active{ color:var(--brand-ink); font-weight:600; }
.cat-filter-check input{ accent-color:var(--brand); flex-shrink:0; }
.cat-filter-check-text{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.cat-filter-dd{ position:relative; }
.cat-filter-dd-toggle{
  width:100%; display:flex; align-items:center; justify-content:space-between; gap:8px;
  background:none; border:1px solid var(--line); border-radius:8px; padding:8px 10px; cursor:pointer; text-align:left;
}
.cat-filter-dd-toggle:hover{ border-color:var(--line-strong); }
.cat-filter-dd.is-open .cat-filter-dd-toggle{ border-color:var(--brand); }
.cat-filter-dd .cat-filter-attr-label{ margin-bottom:0; }
.cat-filter-dd-arrow{
  width:8px; height:8px; border-right:2px solid var(--ink-soft); border-bottom:2px solid var(--ink-soft);
  transform:rotate(45deg); transition:transform .15s; flex-shrink:0;
}
.cat-filter-dd.is-open .cat-filter-dd-arrow{ transform:rotate(225deg); }
.cat-filter-dd-panel{
  position:absolute; top:calc(100% + 4px); left:0; right:0; z-index:1030;
  background:var(--surface); border:1px solid var(--line-strong); border-radius:8px;
  box-shadow:0 8px 20px rgba(0,0,0,.12); padding:8px;
}
.cat-filter-dd-search{ width:100%; font-size:13px; padding:7px 9px; border:1px solid var(--line); border-radius:6px; margin-bottom:6px; }
.cat-filter-dd-search:focus{ outline:none; border-color:var(--brand); }
.cat-filter-dd .cat-filter-checklist{ max-height:220px; }
.cat-filter-dd-empty{ font-size:12.5px; color:var(--muted); padding:6px 4px; }

/* Lives OUTSIDE .cat-filters-scroll as a fixed flex footer, not inside the
   scrolling area — position:sticky nested inside an overflow:auto ancestor
   that itself sits inside a <details>-heavy tree proved unreliable to paint
   correctly in testing. A flex column with a non-scrolling footer avoids
   that class of bug entirely. */
.cat-filter-footer{
  flex-shrink:0; padding:12px 16px; border-top:1px solid var(--line);
  box-shadow:0 -8px 10px -6px rgba(0,0,0,.06);
  display:flex; gap:8px;
}
.cat-filter-reset, .cat-filter-submit{ flex:1; }
.cat-filter-reset.is-disabled{ opacity:.45; }

/* ---- Category/brand filter sidebar as a left-side drawer (<992px) ----
   Same slide-in-panel + dark-overlay mechanic as the header's mobile nav
   drawer (#mobile-drawer in layout.php / style.css above), mirrored to
   open from the LEFT instead of the right — kept as a visually distinct
   direction so it reads as "a different panel" from the nav drawer, not
   a copy of it. Reuses the .mobile-drawer-locked body-scroll-lock class
   already defined for the nav drawer rather than a second copy. */
@media (max-width: 991.98px){
  .cat-filters-drawer-overlay{
    position:fixed; inset:0; background:var(--ink); opacity:0; visibility:hidden;
    z-index:1055; transition:opacity .3s ease, visibility .3s ease;
  }
  .cat-filters-drawer-overlay.cat-filters-drawer-open{ opacity:.65; visibility:visible; }

  .cat-filters{
    position:fixed !important; top:0 !important; left:0; right:auto; width:340px; max-width:88vw; height:100%;
    max-height:none; border-radius:0; border:none; z-index:1060;
    transform:translateX(calc(-100% - 40px));
    transition:transform .3s cubic-bezier(.785,.135,.15,.86);
  }
  .cat-filters.cat-filters-drawer-open{ transform:translateX(0); }
  .cat-filters-scroll{ overflow-y:auto; }
  .cat-filter-footer{ position:static; box-shadow:none; }

  .cat-filters-close{
    display:flex; align-items:center; justify-content:center; width:32px; height:32px; flex-shrink:0;
    border:none; border-radius:99px; background:var(--paper); color:var(--ink-soft);
    transition:background .15s var(--ease), color .15s var(--ease);
  }
  .cat-filters-close:hover{ background:var(--brand-soft); color:var(--brand-ink); }
}

/* "Filters" button in the listing toolbar (listing-toolbar.php),
   <992px only — opens .cat-filters as the drawer above. */
.btn-filters-open{
  display:flex; align-items:center; gap:7px; padding:8px 14px; border:1px solid var(--line-strong); border-radius:99px;
  background:var(--surface); color:var(--ink); font-size:13.5px; font-weight:600;
  transition:border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.btn-filters-open:hover{ border-color:var(--brand); color:var(--brand-ink); box-shadow:var(--shadow-xs); }
.btn-filters-open .n{
  background:var(--brand); color:#fff; border-radius:99px; min-width:18px; height:18px;
  display:inline-flex; align-items:center; justify-content:center; font-size:11px; font-weight:700; padding:0 4px;
}

.stars{ color:#e0a83a; letter-spacing:2px; font-size:15px; }

/* ---- Brand marks strip (homepage) ---- */
.brand-marks{ display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:18px 28px; }
.brand-mark{ display:inline-flex; align-items:center; gap:8px; font-family:var(--font-heading); font-weight:700; font-size:18px; color:var(--muted); letter-spacing:.01em; opacity:.85; transition:color .15s, opacity .15s; }
.brand-mark:hover{ color:var(--brand-ink); opacity:1; }
.brand-mark-icon{ width:20px; height:20px; flex-shrink:0; color:var(--tile-accent, currentColor); opacity:.8; }
.brand-mark-logo{ height:24px; max-width:110px; object-fit:contain; opacity:.85; transition:opacity .15s; }
.brand-mark:hover .brand-mark-logo{ opacity:1; }

/* ---- Testimonials (homepage) ---- */
/* Apple-minimal: no colored top border/badges on cards — plain --paper
   card, star rating kept in its own conventional amber (.stars, defined
   above) since a 5-star rating glyph reads universally in that color and
   isn't part of the retired red/gold brand system. */
.testimonial-card{ position:relative; }
.testimonial-quote-icon{ width:26px; height:26px; color:var(--line-strong); }
.testimonial-card p{ font-size:14px; color:var(--ink-soft); }
.testimonial-avatar{
  display:flex; align-items:center; justify-content:center; width:32px; height:32px; border-radius:99px; flex-shrink:0;
  background:var(--surface); color:var(--ink);
  font-family:var(--font-heading); font-weight:600; font-size:13px;
}
.testimonial-card .author{ font-size:12.5px; font-weight:600; color:var(--ink); }
.testimonial-card .source{ font-size:11.5px; color:var(--muted); }

/* ---- FAQ (homepage) ---- */
.faq-list{ background:var(--line); border-radius:var(--radius); overflow:hidden; }
.faq-item{ background:var(--surface); }
.faq-item summary{ padding:18px 20px; font-weight:500; font-size:15px; cursor:pointer; list-style:none; display:flex; justify-content:space-between; align-items:center; gap:12px; }
.faq-item summary::-webkit-details-marker{ display:none; }
.faq-item-q{ display:flex; align-items:center; gap:10px; }
.faq-item-icon{ width:18px; height:18px; color:var(--muted); flex-shrink:0; }
.faq-item summary::after{ content:'+'; font-size:20px; color:var(--muted); font-weight:300; flex-shrink:0; line-height:1; }
.faq-item[open] summary::after{ content:'−'; }
.faq-item p{ margin:0; padding:0 20px 18px 48px; font-size:14px; color:var(--ink-soft); max-width:70ch; }

/* ---- Store hours / location (homepage) ---- */
.store-info-card{ position:relative; padding-top:24px !important; }
.store-info-icon{
  display:flex; align-items:center; justify-content:center; width:38px; height:38px; border-radius:10px; margin-bottom:12px;
  background:var(--surface); color:var(--ink);
}
.store-info-icon svg{ width:20px; height:20px; }
.store-hours-row{ display:flex; justify-content:space-between; font-size:13px; padding:6px 0; border-bottom:1px solid var(--line-strong); }
.store-hours-row:last-child{ border-bottom:none; }
.store-hours-row.is-today{ font-weight:600; color:var(--brand); }
.store-info-card address{ font-style:normal; font-size:13.5px; color:var(--ink-soft); line-height:1.6; }

/* ---- Contact page map embed ---- */
.contact-map-embed{
  border-radius:var(--radius); overflow:hidden; box-shadow:var(--shadow-sm); border:1px solid var(--line);
}

/* ---- Mobile drawer menu (<992px) ----
   Right-side slide-in panel + dark overlay, mirroring the real
   supertechsys.com site's own offcanvas mechanic (confirmed from its
   theme CSS: fixed, right:0, width 380px / 100% under 380px viewport,
   translateX slide, 0.3s cubic-bezier(.785,.135,.15,.86) ease, dark
   overlay backdrop at opacity .7). Opened/closed by app.js toggling
   .mobile-drawer-open on both elements — not Bootstrap's collapse
   plugin, which animates height, not a horizontal slide. */
.mobile-drawer-overlay{
  position:fixed; inset:0; background:var(--ink); opacity:0; visibility:hidden;
  z-index:1055; transition:opacity .3s ease, visibility .3s ease;
}
.mobile-drawer-overlay.mobile-drawer-open{ opacity:.65; visibility:visible; }

.mobile-drawer{
  position:fixed; top:0; right:0; width:380px; max-width:100%; height:100%;
  background:var(--surface); z-index:1060; overflow-y:auto; -webkit-overflow-scrolling:touch;
  transform:translateX(calc(100% + 40px));
  transition:transform .3s cubic-bezier(.785,.135,.15,.86);
  box-shadow:var(--shadow-lg); display:flex; flex-direction:column;
}
.mobile-drawer.mobile-drawer-open{ transform:translateX(0); }

.mobile-drawer-head{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:18px 18px; border-bottom:1px solid var(--line); flex-shrink:0;
}
.mobile-drawer-close{
  display:flex; align-items:center; justify-content:center; width:36px; height:36px;
  border:none; border-radius:99px; background:var(--paper); color:var(--ink-soft);
  transition:background .15s var(--ease), color .15s var(--ease), transform .12s var(--ease);
}
.mobile-drawer-close:hover{ background:var(--brand-soft); color:var(--brand-ink); }
.mobile-drawer-close:active{ transform:scale(.92); }

.mobile-drawer-body{ padding:16px 14px 32px; flex:1; }

/* Quick-links (Compare/Cart/WhatsApp) — mirrors the desktop
   .header-actions pills, which are d-none below the lg breakpoint (see
   layout.php). Light-panel styling now (previously dark, from when this
   lived inside nav.main's dark collapse dropdown). */
.mobile-quick-links{
  display:flex; flex-direction:column; gap:3px; padding-bottom:14px;
  border-bottom:1px solid var(--line); margin-bottom:14px;
}
.mobile-quick-links a{
  display:flex; align-items:center; gap:11px; padding:10px 10px; border-radius:var(--radius-sm);
  color:var(--ink); font-size:14.5px; font-weight:600; transition:background .15s, transform .12s var(--ease);
}
.mobile-quick-links a:hover, .mobile-quick-links a:focus{ background:var(--paper); }
.mobile-quick-links a:active{ transform:scale(.98); }
/* Icon badge so each quick-link reads as a small button, not a bare icon+text row. */
.mql-icon{
  display:flex; align-items:center; justify-content:center; width:30px; height:30px; border-radius:9px;
  background:var(--paper); color:var(--brand-ink); flex-shrink:0; transition:background .15s;
}
.mobile-quick-links a:hover .mql-icon{ background:var(--brand-soft); }
.mobile-quick-links .n{ background:var(--brand); color:#fff; border-radius:99px; min-width:18px; height:18px; display:inline-flex; align-items:center; justify-content:center; font-size:11px; font-weight:700; padding:0 4px; margin-left:auto; }
.mobile-quick-links .mobile-quick-wa{ background:#25D366; color:#fff; font-weight:700; box-shadow:0 4px 14px -4px rgba(37,211,102,.5); }
.mobile-quick-links .mobile-quick-wa .mql-icon{ background:rgba(255,255,255,.2); color:#fff; }
.mobile-quick-links .mobile-quick-wa:hover{ background:#22c25e; }
.mobile-quick-links .mobile-quick-wa:hover .mql-icon{ background:rgba(255,255,255,.28); }

/* Section label above the category list — gives the drawer two clearly
   separated zones (actions vs. browse) instead of one long list. */
.mobile-nav-label{
  font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.07em;
  color:var(--muted); padding:0 10px 8px;
}

/* Category list — plain links, subcategories expand inline as an
   accordion (see .mobile-drawer-subtoggle) rather than a floating
   Bootstrap dropdown, which doesn't suit a fixed-width side panel. */
.mobile-drawer-nav{ display:flex; flex-direction:column; list-style:none; margin:0; padding:0; }
.mobile-drawer-nav > li{ border-bottom:1px solid var(--line); }
.mobile-drawer-nav > li:last-child{ border-bottom:none; }
/* Covers both a plain <li><a> item AND a has-sub item's <a> nested one
   level deeper inside .mobile-drawer-nav-row — same link styling either way. */
.mobile-drawer-nav > li > a,
.mobile-drawer-nav-row > a{
  display:block; padding:13px 10px; color:var(--ink); font-size:14.5px; font-weight:600;
  border-radius:var(--radius-sm); transition:background .15s, color .15s;
}
.mobile-drawer-nav > li > a:hover,
.mobile-drawer-nav-row > a:hover{ background:var(--paper); color:var(--brand-ink); }
.mobile-drawer-nav-row{ display:flex; align-items:stretch; }
.mobile-drawer-nav-row > a{ flex:1; }
.mobile-drawer-sub{ list-style:none; }
.mobile-drawer-subtoggle{
  display:flex; align-items:center; justify-content:center; width:44px; flex-shrink:0;
  border:none; background:none; color:var(--muted); transition:transform .2s var(--ease), color .15s;
}
.mobile-drawer-subtoggle:hover{ color:var(--brand-ink); }
.mobile-drawer-subtoggle[aria-expanded="true"]{ transform:rotate(180deg); color:var(--brand-ink); }
.mobile-drawer-sub{
  max-height:0; overflow:hidden; padding-left:10px;
  transition:max-height .25s var(--ease);
}
.has-sub.is-open .mobile-drawer-sub{ max-height:600px; }
.mobile-drawer-sub li{ border-left:2px solid var(--line); margin-left:4px; }
.mobile-drawer-sub a{
  display:block; padding:10px 10px 10px 16px; font-size:13.5px; color:var(--ink-soft);
  transition:background .15s, color .15s;
}
.mobile-drawer-sub a:hover{ background:var(--paper); color:var(--brand-ink); }

/* Locks background scroll while the drawer is open (app.js toggles this
   on <body>) so the page behind the overlay doesn't scroll with it. */
body.mobile-drawer-locked{ overflow:hidden; }

@media (max-width:767.98px){
  /* Mobile header row is a 3-column grid: col-3 logo / col-6 search /
     col-3 hamburger (see layout.php — Compare/Cart/WhatsApp pills are
     d-none here, their mobile equivalent is .mobile-quick-links above,
     inside the dropdown the hamburger opens). col-3 is only ~80-95px
     wide on a phone — logo stays full size (user asked to keep it fixed,
     not shrink on mobile), so .logo's own overflow/ellipsis (base rule
     above) truncates "SuperTechSys" to "SuperTe…" rather than shrinking
     the font or breaking the layout. */
  .search-box{ max-width:100%; }
  /* Slightly elevated/filled look instead of the flat grey desktop input
     — a subtle shadow + a touch more background contrast so it reads as
     a distinct tappable surface at the smaller mobile size. */
  .search-box input{
    padding-left:34px; font-size:13px; background:var(--surface);
    border-color:var(--line); box-shadow:0 1px 3px rgba(1,15,28,.06);
  }
  .search-box input:focus{ box-shadow:0 0 0 4px var(--brand-soft); }
  .search-box svg{ left:11px; width:13px; height:13px; }

  /* Contact bar is tight at phone widths once the social icons are added
     (390px: phone number was wrapping to 2 lines, social icons crowded
     against the edge). Tighter gap + drop the "WhatsApp:" label (icon +
     number is enough, and social links are already icon-only) frees
     enough room to keep everything on one line. */
  .header-contact-bar{ gap:12px; }
  .hcb-label{ display:none; }
  .hcb-social{ gap:6px; }

  /* On mobile, once the user scrolls down past the top of the page,
     app.js adds .header-scrolled to header.site. The logo/search/menu
     grid row always stays visible (it's the core header now, logo size
     fixed — see above), but the contact bar collapses away entirely, so
     the sticky header still takes up less vertical space while scrolling. */
  header.site.header-scrolled .header-contact-bar{
    max-height:0; opacity:0; padding-top:0; padding-bottom:0; border-color:transparent;
  }
  header.site.header-scrolled .header-inner{ padding-top:8px; padding-bottom:8px; }
  /* Toggler shrinks slightly too once scrolled, matching the more compact header. */
  header.site.header-scrolled .navbar-toggler{ width:36px; height:36px; }
  header.site.header-scrolled .navbar-toggler-bars{ width:15px; height:11px; }
  header.site.header-scrolled .navbar-toggler-bar{ width:15px; }
  header.site.header-scrolled .navbar-toggler-bar:nth-child(2){ top:4.5px; }
  header.site.header-scrolled .navbar-toggler-bar:nth-child(3){ top:9px; }
  header.site.header-scrolled .navbar-toggler[aria-expanded="true"] .navbar-toggler-bar:nth-child(1),
  header.site.header-scrolled .navbar-toggler[aria-expanded="true"] .navbar-toggler-bar:nth-child(3){ top:4.5px; }
}

/* ---- Admin: product editor (out of scope for this conversion; unchanged) ---- */
.pf-header{ display:flex; justify-content:space-between; align-items:flex-start; gap:16px; margin-bottom:18px; flex-wrap:wrap; }
.pf-header h1{ margin-bottom:4px; }
.pf-meta{ font-size:12.5px; color:var(--muted); }
.pf-meta b{ color:var(--ink); }
.pf-flash{
  display:flex; align-items:center; gap:8px; background:var(--ok-bg); color:var(--ok);
  border:1px solid var(--ok); border-radius:8px; padding:9px 14px; font-size:13.5px;
  font-weight:600; margin-bottom:18px;
}
.pf-flash svg{ width:16px; height:16px; flex-shrink:0; }

.pf-layout{ display:grid; grid-template-columns:1fr 300px; gap:20px; align-items:start; }
.pf-main{ display:flex; flex-direction:column; gap:16px; min-width:0; }
.pf-side{ display:flex; flex-direction:column; gap:16px; position:sticky; top:16px; }

.pf-card{ background:var(--surface); border:1px solid var(--line); border-radius:10px; box-shadow:var(--shadow); padding:18px 20px; }
.pf-card > h3{
  font-size:13px; text-transform:uppercase; letter-spacing:.04em; font-family:inherit;
  font-weight:700; color:var(--brand-ink); margin:0 0 14px; padding-bottom:10px;
  border-bottom:1px solid var(--line);
}
.pf-card > p.pf-hint{ font-size:12px; color:var(--muted); margin:-8px 0 12px; }

.pf-actions{ display:flex; flex-direction:column; gap:10px; }
.pf-actions .btn{ width:100%; justify-content:center; }
.pf-checkbox-row{ display:flex; align-items:center; gap:8px; font-size:13px; padding-top:2px; }
.pf-checkbox-row input{ width:auto; margin:0; }
.pf-checkbox-row label{ margin:0; font-size:13px; font-weight:500; color:var(--ink); text-transform:none; }

.pf-cat-filter{ width:100%; padding:8px 11px; margin-bottom:16px; font-family:inherit; font-size:13px; border:1px solid var(--line-strong); border-radius:6px; background:var(--paper); }
.pf-cat-group{ margin-bottom:16px; }
.pf-cat-group:last-child{ margin-bottom:0; }
.pf-cat-group-title{ margin:0 0 8px; font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); }
.pf-cat-list{ display:flex; flex-wrap:wrap; gap:8px; }

.pf-image-grid{ display:flex; flex-wrap:wrap; gap:12px; margin-bottom:14px; }
.pf-image-tile{ width:104px; }
.pf-image-frame{ position:relative; border:2px solid var(--line); border-radius:8px; overflow:hidden; aspect-ratio:1; background:var(--paper); }
.pf-image-tile.is-featured .pf-image-frame{ border-color:var(--brand); box-shadow:0 0 0 1px var(--brand); }
.pf-image-frame img{ width:100%; height:100%; object-fit:cover; }
.pf-featured-badge{
  position:absolute; top:5px; left:5px; background:var(--brand); color:#fff; font-size:9.5px;
  font-weight:700; letter-spacing:.03em; text-transform:uppercase; padding:2px 6px; border-radius:99px;
}
.pf-image-controls{ display:flex; flex-direction:column; gap:2px; margin-top:6px; }
.pf-image-controls label{ display:flex; align-items:center; gap:5px; font-size:11px; cursor:pointer; margin:0; font-weight:500; text-transform:none; color:var(--ink-soft); }
.pf-image-controls input{ width:auto; margin:0; }
.pf-image-controls .pf-delete-label{ color:var(--danger); }

.pf-upload{ border:1.5px dashed var(--line-strong); border-radius:8px; padding:14px 16px; background:var(--paper); font-size:13px; }
.pf-upload input[type=file]{ width:100%; font-size:12.5px; font-family:inherit; }

.pf-spec-groups{ display:grid; grid-template-columns:1fr 1fr; gap:12px; align-items:start; background:none; border:none; overflow:visible; }
.pf-spec-col{ display:flex; flex-direction:column; gap:12px; min-width:0; }
.pf-spec-group{ background:var(--paper); border:1px solid var(--line); border-radius:8px; padding:14px 16px; min-width:0; }
.pf-spec-group-head{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; margin:0 0 12px; }
.pf-spec-group h5{ font-size:11.5px; letter-spacing:.05em; text-transform:uppercase; color:var(--brand-ink); margin:0; font-weight:700; }
.pf-spec-group-count{ font-size:11px; color:var(--muted); white-space:nowrap; }
.pf-spec-fields{ display:grid; grid-template-columns:1fr 1fr; gap:10px 12px; }
.pf-spec-field{ min-width:0; }
.pf-spec-field.is-wide{ grid-column:1 / -1; }
.pf-spec-field label{ display:flex; align-items:center; gap:5px; font-size:11px; color:var(--ink-soft); text-transform:none; font-weight:600; margin-bottom:4px; }
.pf-spec-field select, .pf-spec-field input{ width:100%; max-width:100%; padding:7px 9px; font-size:12.5px; box-sizing:border-box; }
.pf-spec-field .attr-new-input{ margin-top:6px; }
.pf-spec-field.is-empty select{ color:var(--muted); border-style:dashed; }
.pf-spec-dot{ width:6px; height:6px; border-radius:99px; background:var(--line-strong); flex-shrink:0; }
.pf-spec-field:not(.is-empty) .pf-spec-dot{ background:var(--ok); }

@media (max-width:480px){
  .pf-spec-fields{ grid-template-columns:1fr; }
}

.pf-price-row{ display:grid; grid-template-columns:1fr 1fr; gap:14px; }

@media (max-width:980px){
  .pf-layout{ grid-template-columns:1fr; }
  .pf-side{ position:static; }
  .pf-price-row{ grid-template-columns:1fr; }
  .pf-spec-groups{ grid-template-columns:1fr; }
}

/* ---- Admin: dashboard (2026-09-25) ----
   Was borrowing the public homepage's .cat-tile class directly (no real
   component of its own). Rebuilt with its own namespace, reusing the same
   --brand/--radius/--shadow/--ease tokens the public Apple-minimal refresh
   uses, so admin feels like the same product rather than a bolted-on tool.
   Scope: dashboard page only — the dark .admin-bar nav and every other
   admin page (products list, categories, etc.) are untouched. */
.admin-dash-head{ display:flex; align-items:flex-end; justify-content:space-between; gap:16px; flex-wrap:wrap; margin-bottom:24px; }
.admin-dash-head h1{ margin:0 0 4px; }
.admin-dash-sub{ font-size:13.5px; color:var(--muted); margin:0; }

.admin-stat-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:14px; }
.admin-stat-card{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:var(--shadow-xs); padding:20px 20px 18px; display:flex; flex-direction:column; gap:10px;
  transition:transform .15s var(--ease), box-shadow .15s var(--ease), border-color .15s var(--ease);
  text-decoration:none; color:inherit; cursor:pointer;
}
.admin-stat-card:hover{ transform:translateY(-2px); box-shadow:var(--shadow); border-color:var(--brand); color:inherit; }
.admin-stat-card:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
.admin-stat-icon{
  width:36px; height:36px; border-radius:10px; display:flex; align-items:center; justify-content:center;
  background:var(--brand-soft); color:var(--brand-ink); flex-shrink:0;
}
.admin-stat-icon svg{ width:18px; height:18px; }
.admin-stat-card.is-warn .admin-stat-icon{ background:var(--danger-bg); color:var(--danger); }
.admin-stat-card.is-ok .admin-stat-icon{ background:var(--ok-bg); color:var(--ok); }
.admin-stat-value{ font-family:var(--font-heading); font-size:26px; font-weight:800; color:var(--ink); line-height:1.1; }
.admin-stat-label{ font-size:12.5px; color:var(--muted); font-weight:500; }
.admin-stat-card.is-warn .admin-stat-value{ color:var(--danger); }

.admin-dash-section{ margin-top:32px; }
.admin-dash-section-title{
  font-size:12px; text-transform:uppercase; letter-spacing:.05em; font-weight:700;
  color:var(--muted); margin:0 0 12px;
}

.admin-action-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:12px; }
.admin-action-card{
  display:flex; align-items:center; gap:12px; background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius-sm); padding:14px 16px; color:var(--ink); font-weight:600; font-size:13.5px;
  transition:border-color .15s var(--ease), box-shadow .15s var(--ease), transform .15s var(--ease);
}
.admin-action-card:hover{ border-color:var(--brand); box-shadow:var(--shadow-xs); transform:translateY(-1px); color:var(--ink); }
.admin-action-card svg{ width:20px; height:20px; color:var(--brand); flex-shrink:0; }
.admin-action-card.is-primary{ background:var(--brand); border-color:var(--brand); color:#fff; }
.admin-action-card.is-primary svg{ color:#fff; }
.admin-action-card.is-primary:hover{ background:var(--brand-ink); border-color:var(--brand-ink); color:#fff; }

.admin-dash-note{
  display:flex; gap:10px; align-items:flex-start; background:var(--paper); border:1px solid var(--line);
  border-radius:var(--radius-sm); padding:14px 16px; font-size:13px; color:var(--ink-soft); margin-top:28px;
}
.admin-dash-note svg{ width:16px; height:16px; color:var(--muted); flex-shrink:0; margin-top:1px; }
.admin-dash-note code{ background:var(--line); padding:1px 5px; border-radius:4px; font-size:12px; }

@media (max-width:1180px){
  .admin-stat-grid{ grid-template-columns:repeat(2,1fr); }
}
@media (max-width:980px){
  .admin-action-grid{ grid-template-columns:repeat(2,1fr); }
}
@media (max-width:560px){
  .admin-stat-grid{ grid-template-columns:1fr; }
  .admin-action-grid{ grid-template-columns:1fr; }
}
