/* =========================================================================
   BOTRIX -- DESIGN SYSTEM v19 (Premium Robotics)
   Minimalist industrial design language. Electric Cyan on Deep Graphite.
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Roboto+Mono:wght@400;500;700&display=swap');

:root {
  /* Inherits base palette from design-system.css, but adds specific structural aliases */
  --bg: var(--background);
  --bg-alt: var(--surface-alt);
  --text: var(--text-primary);
  --ink: var(--background); /* Text color for inverted panels */
  --muted: var(--text-muted);
  --gray: var(--text-secondary);
  --success: var(--c-success);
  --warning: var(--c-warning);
  --error: var(--c-error);
  --error-text: #FF6B6B;
  --success-text: #00E5FF;
  
  --glass-bg: var(--surface);
  --glass-bg-hover: var(--surface-alt);
  --glass-bg-strong: #222222;
  --glass-border: var(--border);
  --glass-border-hover: var(--primary);
  --glass-blur: 0px;

  /* Typography */
  --font-display: var(--font-sans);
  --font-body: var(--font-sans);

  /* Radius */
  --radius-s: 0px; 
  --radius-m: 2px; 
  --radius-l: 4px;
  --radius-round: var(--radius-m);

  /* Shadows */
  --shadow-card: none;
  --shadow-lift: 0 10px 30px rgba(0, 0, 0, 0.8);
  --shadow-premium: 0 20px 40px rgba(0, 0, 0, 0.9);
  --container: 1400px;

  /* Typography Scale */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
  --text-3xl: 2rem;

  /* Form/Button Sizes */
  --btn-h-sm: 32px;
  --btn-h-md: 40px;
  --btn-h-lg: 48px;
  --input-h-md: 40px;
}

*{box-sizing:border-box;}
html{
  overflow-x:hidden;
  width:100%;
  background:#060608 !important;
  color-scheme:dark;
}
body{
  margin:0;
  font-family:var(--font-body);
  color:var(--text);
  background:#060608 !important;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  min-height:100vh;
  position:relative;
  padding-top:88px; 
}
@media(max-width:1024px){body{padding-top:76px;}}
img{max-width:100%;display:block;}
a{color:inherit;text-decoration:none;}
h1,h2,h3,h4{
  font-family:var(--font-display);
  color:var(--text);
  line-height:1.1;
  margin:0 0 0.5em;
  font-weight:700;
  letter-spacing:-0.03em;
  text-transform: uppercase;
}
h1{font-size:clamp(2.5rem,4vw,3.5rem);font-weight:700;letter-spacing:-0.04em;}
.hero h1{font-size:clamp(3rem,6vw,5.5rem);font-weight:700;letter-spacing:-0.05em;line-height:1;margin-bottom:24px;};}
h2{font-size:clamp(1.7rem,3.2vw,2.7rem);}
h3{font-size:1.25rem;font-weight:700;letter-spacing:-0.01em;}
p{margin:0 0 1em;color:var(--gray);}
.mono{font-family:var(--font-mono);}
/* .text-gradient used to fade text through three shades of the same acid
   green. Kept as a no-op selector because several templates still carry the
   class; it now simply renders as normal emphasis. */
.text-gradient{color:var(--primary);}

.container{max-width:var(--container);margin:0 auto;padding:0 24px;position:relative;z-index:1;}
@media(min-width:1025px){.container{padding:0 56px;}}
@media(min-width:1900px){:root{--container:1900px;}}
.section{padding:80px 0;}
.section-alt{background:var(--bg-alt);border-top:1px solid var(--glass-border);border-bottom:1px solid var(--glass-border);position:relative;}
/* `.section-glow-kit`, `.section-glow-iot` and `.section-glow-store` used to be three
   separate wrappers here, each painting a 520px blurred radial blob in a ::before --
   rose behind #kits, amber behind #iot, orange behind #store -- at blur(90px) and
   opacity 0.5. Two of those three hues are not in the palette at all any more, but the
   bigger problem is what they are: a soft-focus coloured orb bleeding out of a section
   corner is the most reproduced decoration on the landing-page internet, and on this
   homepage in particular they sat directly behind the 3D robot and washed it out.
   `overflow:hidden` went with the blobs: it existed to clip them, and with nothing to
   clip it only risked cutting off a child that wanted to overflow.

   What was left was one rule doing `position:relative` under three names that all
   promised a glow, on a site where a stray halo is the thing being hunted. The three
   are now one honest class -- `.section-stack`, which is all it ever does: give the
   section a stacking context so its .container can sit at z-index 1 above the fixed
   3D canvas at z-index -1. index.php:286/337/380 carry it. */
.section-stack{position:relative;}
.section-stack .container{position:relative;z-index:1;}

.stats-band{padding:52px 0;background:var(--surface-2);border-top:1px solid var(--glass-border);border-bottom:1px solid var(--glass-border);position:relative;}
/* Was a 6px gold dot dead-centre of the band carrying
   `box-shadow:0 0 16px 4px rgba(239,177,29,0.35)` -- a bare glowing point with
   no meaning attached to it, floating between the four figures. */
.stats-band-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:24px;text-align:center;}
/* The figures were italic, and filled with a left-to-right gradient clipped to
   the glyphs via `background-clip:text;color:transparent`. Gradient-filled
   numerals are a signature of the same template family as the orbs above, and
   the technique fails loudly: if the gradient does not paint, `color` is
   transparent and the number is simply not there. Solid gold, upright. */
.stats-band-grid div strong{display:block;font-family:var(--font-display);font-size:2.2rem;font-weight:800;color:var(--primary);}
.stats-band-grid div span{font-size:0.85rem;color:var(--gray);letter-spacing:0.02em;}
@media(max-width:768px){.stats-band-grid{grid-template-columns:repeat(2,1fr);gap:32px 20px;}}
@media(min-width:1025px){.section{padding:100px 0;}}

/* Was gold, bold, ALL CAPS, with a 7px filled circle in front of it, on every
   section of every page. The dot-plus-coloured-eyebrow pair is the most copied
   landing-page motif there is, and it read as decoration rather than as a
   label. Kept: mono and uppercase, which on a hardware site reads like a
   datasheet section marker. Changed: muted instead of accent, so the heading
   below it is the thing your eye lands on, and a short hairline rule in place
   of the dot. */
.section-eyebrow{font-family:var(--font-mono);font-size:0.72rem;letter-spacing:0.15em;text-transform:uppercase;color:var(--muted);display:inline-flex;align-items:center;gap:11px;margin-bottom:16px;font-weight:600;}
.section-eyebrow::before{content:'';width:20px;height:1px;background:var(--border);flex-shrink:0;}
.section-head{max-width:640px;margin-bottom:48px;}
.text-center{text-align:center;margin-left:auto;margin-right:auto;}

/* Cards -- clean light editorial cards, subtle hairline border, soft shadow */
.glass-card,.pillar-card,.product-card,.form-card,.cart-summary,.leader-card,.stat-card,.admin-card,.empty-state,.faq-item{
  
  background:var(--surface);border:1px solid var(--glass-border);border-radius:var(--radius-m);
  box-shadow:var(--shadow-card);transition:transform 0.25s cubic-bezier(.2,.8,.2,1),box-shadow 0.25s ease,border-color 0.25s ease;
  position:relative;
}
.glass-card:hover,.pillar-card:hover,.product-card:hover,.leader-card:hover,.stat-card:hover{
  transform:translateY(-4px);box-shadow:var(--shadow-lift);border-color:var(--glass-border-hover);
}
.glass-card{padding:32px;}

/* "Why Botrix" feature cards -- a larger icon with a tasteful hover lift,
   scoped to .feature-card specifically rather than every .glass-card
   (which is used broadly across the site in unrelated contexts). */
.feature-card{transition:transform 0.25s ease,box-shadow 0.25s ease;}
.feature-card:hover{transform:translateY(-4px);}
.feature-card-icon{
  display:inline-block;font-size:2.2rem;line-height:1;margin-bottom:14px;
  transition:transform 0.4s cubic-bezier(.34,1.56,.64,1);
}
.feature-card:hover .feature-card-icon{transform:scale(1.15) rotate(-4deg);}
@media(prefers-reduced-motion:reduce){
  .feature-card,.feature-card-icon,.feature-card:hover,.feature-card:hover .feature-card-icon{transition:none;transform:none;}
}

/* Circular progress ring (e.g. learning path completion) -- animates
   its fill from 0 to the real tracked percentage once scrolled into
   view, driven by a data-percent attribute set from actual progress
   data, not a decorative placeholder. */
.progress-ring-wrap{position:relative;width:100px;height:100px;flex-shrink:0;}
.progress-ring{width:100%;height:100%;transform:rotate(-90deg);}
.progress-ring-track{fill:none;stroke:var(--glass-border);stroke-width:8;}
.progress-ring-fill{
  fill:none;stroke:var(--c-success);stroke-width:8;stroke-linecap:round;
  stroke-dasharray:263.89;stroke-dashoffset:263.89;
  transition:stroke-dashoffset 1.1s cubic-bezier(.25,.8,.25,1);
}
.progress-ring-label{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-family:var(--font-display);font-weight:800;font-size:1.15rem;color:var(--text);
}
@media(prefers-reduced-motion:reduce){
  .progress-ring-fill{transition:none;}
}


/* Buttons
   Three things were wrong in this block after the palette moved to ENIG gold on
   FR4 green, and all three were live on shipped pages:

   1. `.btn-primary` was `color:#fff` over `var(--primary)`. That passed while
      --primary was a dark orange; gold #C89B3C behind white text measures about
      2.6:1, well under the 4.5:1 WCAG AA asks for. The ink #060D0B that
      emods.css already uses for the hero CTA gives 7.7:1 on the same gold.

   2. `--ink` used to be a near-black. It holds bone #EDE7D9 now, so
      `.btn-buy-now` and `.btn-secondary:hover` were painting white text on a
      near-white fill: the Buy Now button on every store-detail page was
      readable only by its own shadow. This is the kind of break a palette swap
      leaves behind when the token name stops describing the value.

   3. The shadows were tints of rgba(228,61,18,...), the pre-redesign orange --
      a hue that is not in the palette any more. scripts/deglow.mjs skipped them
      because that tint is not in its TINT regex.

   The 999px pill went too: --radius-m is 4px, and a stadium-shaped button is
   the single most recognisable stock-template shape there is. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:var(--font-body);font-weight:700;font-size:0.92rem;padding:13px 26px;border-radius:var(--radius-m);border:none;cursor:pointer;transition:background 0.18s ease,border-color 0.18s ease,color 0.18s ease,transform 0.18s ease;white-space:nowrap;}
.btn-primary{background:var(--primary);color:var(--bg);}
.btn-primary:hover{background:var(--primary-hover);}
.btn-secondary{background:transparent;color:var(--text);border:1.5px solid var(--border);padding:11.5px 24px;}
.btn-secondary:hover{background:var(--surface-2);border-color:var(--primary);color:var(--primary);}
.btn-buy-now{background:var(--ink);color:var(--bg);}
.btn-buy-now:hover{background:var(--primary);color:var(--bg);}
.btn-cart{background:transparent;border:1.5px solid var(--border);color:var(--text);}
.btn-cart:hover{border-color:var(--primary);color:var(--primary);}
/* WhatsApp brand green with white on it is 2:1. The logo lockup gets away with
   that; a button with words in it does not. Ink on the same green is 9.9:1. */
.btn-whatsapp{background:#25D366;color:var(--bg);}
.btn-whatsapp:hover{background:#1FB855;}
.btn-share{background:var(--surface-2);color:var(--text);border:1px solid var(--border);}
.btn-block{width:100%;}
.btn-sm{padding:9px 18px;font-size:0.82rem;}
.btn svg{width:17px;height:17px;flex-shrink:0;}

/* =========================================================================
   NAVBAR -- minimal top bar, logo left / links right (matches reference)
   ========================================================================= */
.navbar-wrap{position:fixed!important;top:0!important;left:0!important;right:0!important;width:100%!important;max-width:100%!important;transform:none!important;z-index:300;background:var(--bg)!important;border-bottom:1px solid var(--glass-border);padding:0!important;box-shadow:none!important;}
.navbar{display:block;background:none;}
.navbar,.navbar-wrap>nav{width:100%;}
.nav-unified-island,.navbar-island{
  display:flex!important;align-items:center!important;justify-content:space-between!important;
  gap:20px;height:76px;
  max-width:var(--container);margin:0 auto;padding:0 24px;
  background:none!important;border:none!important;box-shadow:none!important;border-radius:0!important;
}
@media(min-width:1025px){.nav-unified-island,.navbar-island{padding:0 56px;}}

.brand,.nav-brand{display:flex;align-items:center;gap:10px;flex-shrink:0;}
.brand img,.nav-brand img{height:26px;width:auto;display:block;}

.nav-sep{width:1px;height:20px;background:var(--glass-border-hover);flex-shrink:0;margin:0 4px;}
.nav-sep:nth-of-type(1){display:none;} /* hide sep next to logo -- matches reference's plain spacing */

.nav-links{display:flex;align-items:center;gap:2px;list-style:none;margin:0;padding:0;flex:1;justify-content:flex-end;}
.nav-links::-webkit-scrollbar{display:none;}
.nav-links>li{position:relative;flex-shrink:0;}
.nav-links>li>a{
  font-weight:700;font-size:0.78rem;letter-spacing:0.09em;text-transform:uppercase;
  padding:8px 14px;border-radius:var(--radius-m);display:inline-flex;align-items:center;gap:5px;
  color:var(--text);cursor:pointer;background:none;border:none;font-family:var(--font-body);
  transition:all 0.18s ease;white-space:nowrap;
}
.nav-links>li>a::before{content:'\2022';color:var(--primary);margin-right:7px;font-size:0.9em;}
.nav-links>li>a:hover{color:var(--primary);background:rgba(200, 155, 60,0.06);}

/* Dropdown nav parents (Store / Learn) */
.has-dropdown{position:relative;}
.nav-parent-link{position:relative;}
.nav-parent-link::after{content:'';display:inline-block;width:6px;height:6px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg);margin-left:6px;margin-bottom:1px;transition:transform 0.18s ease;}
.has-dropdown:hover .nav-parent-link::after,.has-dropdown:focus-within .nav-parent-link::after{transform:rotate(-135deg);}
.dropdown-menu{
  position:absolute;top:calc(100% + 10px);left:50%;transform:translateX(-50%);
  min-width:220px;background:var(--surface);border:1.5px solid var(--glass-border-hover);
  border-radius:var(--radius-m);box-shadow:var(--shadow-lift);padding:8px;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity 0.18s ease,transform 0.18s ease,visibility 0.18s ease;
  z-index:310;
}
.has-dropdown.dropdown-open .dropdown-menu{
  opacity:1;visibility:visible;pointer-events:auto;transform:translateX(-50%) translateY(0);
}
.dropdown-menu a{
  display:block;padding:10px 14px;border-radius:10px;font-size:0.84rem;font-weight:600;
  text-transform:none;letter-spacing:normal;color:var(--text);white-space:nowrap;
}
.dropdown-menu a::before{display:none;}
.dropdown-menu a:hover{background:var(--surface-2);color:var(--primary);}

.nav-mobile-only{display:none;}

.nav-actions{display:flex;align-items:center;gap:6px;flex-shrink:0;}
.icon-btn{position:relative;display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:50%;transition:background 0.18s ease;color:var(--text);}
.icon-btn:hover{background:var(--surface-2);color:var(--primary);}
.icon-btn svg{width:18px;height:18px;stroke:currentColor;}
/* Ink, not white: this is 0.6rem type on gold, the smallest text on the site,
   and white on #C89B3C is 2.6:1. The 50% radius stays -- a count bubble is one
   of the few things on the page that is genuinely a circle. */
.cart-badge,.wishlist-badge{position:absolute;top:0;right:0;background:var(--primary);color:var(--bg);font-size:0.6rem;font-weight:800;min-width:16px;height:16px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-family:var(--font-mono);}

/* Wishlist heart button -- used on catalog cards, detail pages, and full-width variant */
.wishlist-form{display:inline-flex;flex-shrink:0;}
.wishlist-form.full{width:100%;}
.wishlist-btn{
  display:inline-flex;align-items:center;justify-content:center;
  width:42px;height:42px;border-radius:50%;flex-shrink:0;
  background:var(--surface);border:1.5px solid var(--glass-border-hover);
  color:var(--text);cursor:pointer;transition:all 0.18s ease;
}
.wishlist-btn svg{width:19px;height:19px;stroke:currentColor;flex-shrink:0;}
/* Both states were copper -- var(--accent) on hover, var(--secondary) when saved --
   and a wishlist button lives on a .product-card, i.e. on --surface, where copper is
   3.25:1. Gold is 5.49:1 on the card and 4.86:1 on the 14% copper tint the active
   state fills with, so the tint stays (it is a fill, and copper is a fill hue) and
   only the glyph changes. */
.wishlist-btn:hover{border-color:var(--primary);color:var(--primary);}
.wishlist-btn.active{background:rgba(180,101,58,0.14);border-color:var(--secondary);color:var(--primary);}
.wishlist-btn-full{
  width:100%;height:auto;border-radius:var(--radius-m);gap:8px;
  padding:13px 26px;font-weight:700;font-size:0.92rem;
}
.wishlist-btn-full svg{width:17px;height:17px;}
@media(max-width:480px){
  .wishlist-btn{width:38px;height:38px;}
  .wishlist-btn svg{width:17px;height:17px;}
}
.login-pill{display:inline-flex;align-items:center;gap:8px;padding:7px 16px 7px 7px;border-radius:var(--radius-m);background:var(--surface-2);border:1px solid var(--glass-border);font-weight:700;font-size:0.82rem;transition:all 0.18s ease;}
.login-pill:hover{background:var(--ink);color:var(--bg);border-color:var(--text);}
/* A 24px circle is too small to show a gradient as anything but a smudge, and
   the two stops were --primary and --accent, which is gold to copper -- white
   initials measured under 3:1 against both ends. Solid gold, ink initials. */
.login-pill .avatar{width:24px;height:24px;border-radius:50%;background:var(--primary);display:flex;align-items:center;justify-content:center;font-size:0.68rem;font-weight:800;color:var(--bg);}

/* Search: single clean button, no category dropdown */
.search-toggle{background:none;border:none;cursor:pointer;}
#mobileSearchWrap{display:none;position:absolute;top:76px;left:0;right:0;z-index:299;background:var(--bg);border-bottom:1px solid var(--glass-border);padding:16px 24px;}
#mobileSearchWrap.search-open{display:block;}
#mobileSearchWrap .container{height:auto;display:block;padding:0;}
.nav-search{position:relative;flex:0 0 auto;max-width:560px;margin:0 auto;}
.nav-search input{width:100%;padding:12px 18px 12px 42px;border-radius:var(--radius-m);border:1.5px solid var(--glass-border-hover);background:var(--surface);color:var(--text);font-size:0.92rem;}
.nav-search input::placeholder{color:var(--gray);}

.search-suggestions{position:absolute;top:calc(100% + 6px);left:0;right:0;background:var(--bg);border:1px solid var(--glass-border);border-radius:var(--radius-m);box-shadow:0 12px 32px rgba(0,0,0,0.15);z-index:500;max-height:340px;overflow-y:auto;display:none;}
.search-suggestions.open{display:block;}
.search-suggestion-item{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:10px 16px;text-decoration:none;color:var(--text);font-size:0.88rem;border-bottom:1px solid var(--glass-border);}
.search-suggestion-item:last-child{border-bottom:none;}
.search-suggestion-item:hover{background:var(--surface-2);}
.ssi-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.ssi-type{flex-shrink:0;font-size:0.72rem;color:var(--gray);text-transform:uppercase;letter-spacing:0.03em;}
.nav-search input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px rgba(200, 155, 60,0.12);}
.nav-search svg{position:absolute;left:16px;top:50%;transform:translateY(-50%);width:16px;height:16px;stroke:var(--gray);}
.nav-toggle{display:none;background:none;border:none;cursor:pointer;color:var(--text);}

@media(max-width:980px){
  .nav-links{display:none;}
  .nav-links.open{
    display:flex !important;position:fixed !important;top:82px !important;left:0 !important;right:0 !important;bottom:0 !important;
    width:100% !important;height:auto !important;background:var(--bg) !important;z-index:2147483647 !important;
    flex-direction:column !important;overflow-y:auto !important;padding:20px !important;
  }
  .nav-toggle,.search-toggle{display:flex;align-items:center;justify-content:center;}
  .nav-unified-island,.navbar-island{height:68px;padding:0 16px;}
  /* Inside the mobile fullscreen menu, dropdowns render as static
     always-open sub-lists (no hover on touch devices). */
  .dropdown-menu{
    position:static;transform:none;opacity:1;visibility:visible;pointer-events:auto;
    box-shadow:none;border:none;background:none;padding:0 0 6px 18px;min-width:0;
  }
  .nav-parent-link::after{display:none;}
  .has-dropdown{display:flex;flex-direction:column;align-items:flex-start;width:100%;}
}

/* =========================================================================
   HERO -- big bold italic display type, cream bg, subtle color accents
   ========================================================================= */
/* =========================================================================
   COMING SOON -- countdown banner, admin-toggleable
   ========================================================================= */
/* This band was `background:var(--ink)` with white text, which read as a dark
   inverted strip while --ink was a near-black. --ink holds bone #EDE7D9 now, so
   it had become white text on an almost-white panel. Every child rule below
   assumes a dark ground -- the title, the message and the countdown chips are
   all white or translucent white -- so the honest fix is to name the dark
   surface the band always meant, not to invert six rules. It carries no
   .section class, so the transparent override in emods.css does not reach it
   and a solid strip is allowed here. */
.coming-soon-banner{
  background:var(--bg-alt);color:var(--white);text-align:center;
  padding:36px 20px;position:relative;
  border-bottom:1px solid var(--border);
}
/* Was `color:var(--pink)` behind a 7px filled dot. The dot is the motif already
   taken off .section-eyebrow, and the label's own text starts with `//` -- it
   did not need a second marker in front of that. */
.coming-soon-eyebrow{
  font-family:var(--font-mono);font-size:0.76rem;letter-spacing:0.16em;text-transform:uppercase;
  color:var(--muted);display:inline-flex;align-items:center;gap:8px;margin-bottom:10px;font-weight:600;position:relative;
}
.coming-soon-title{
  font-family:var(--font-display);font-weight:800;
  font-size:clamp(1.8rem,4vw,3rem);color:var(--white);margin:0 0 8px;position:relative;letter-spacing:-0.02em;
}
.coming-soon-message{color:var(--muted);margin:0 0 24px;position:relative;font-size:0.95rem;}
.coming-soon-countdown{
  display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;position:relative;
}
.cs-unit{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  background:var(--surface-2);border:1px solid var(--border);
  border-radius:var(--radius-m);min-width:76px;padding:12px 10px;
}
.cs-num{
  font-family:var(--font-mono);font-weight:700;font-size:1.8rem;line-height:1;
  color:var(--primary);
}
.cs-label{font-size:0.68rem;text-transform:uppercase;letter-spacing:0.06em;color:var(--muted);margin-top:4px;}
/* The separator between the countdown numerals was color:var(--border) -- a hairline
   colour, rgba(255,255,255,0.1), used on 1.6rem type. That is 1.38:1 on the page
   ground: the colons between the digits were not visible at all. --muted is the 62%
   bone the rest of the site's secondary type uses, 5.33:1 on the worst ground here,
   and it stays a step below the gold .cs-num it separates. */
.cs-sep{font-family:var(--font-mono);font-size:1.6rem;font-weight:700;color:var(--muted);}
@media(max-width:640px){
  .coming-soon-banner{padding:28px 16px;}
  .cs-unit{min-width:60px;padding:9px 6px;}
  .cs-num{font-size:1.3rem;}
  .cs-sep{font-size:1.1rem;}
}

.hero{position:relative;overflow:hidden;padding:80px 0 96px;min-height:560px;display:flex;align-items:center;justify-content:flex-start;}
.hero .container{position:relative;z-index:2;width:100%;max-width:100%;margin:0;padding:0 24px;text-align:left;}
@media(min-width:1025px){.hero .container{padding:0 56px;}}
.hero-text-col{max-width:600px;text-align:left;}
.hero-text-col *{text-align:left;}

/* Full-bleed background media layer -- an uploaded image, gif or video.
   3D no longer lands here: the model used to be mounted in #heroModelCanvas
   inside this box by an inline three.js r128 script in index.php. It is now a
   full-page scene in #robotBg (see src/3d/main.js), so the two rules that sized
   that canvas are gone -- the ids they targeted no longer exist. */
.hero-bg-media{position:absolute;inset:0;z-index:0;overflow:hidden;}
.hero-bg-media img,.hero-bg-media video{width:100%;height:100%;object-fit:cover;object-position:75% center;display:block;}

/* Scrim behind the hero copy, fading out to the right so the 3D robot reads
   through the far side. The comment here used to say "solid cream", which it has
   not been for two palettes; the stops were rgba(14,15,18), a cool near-black
   left over from the same dark theme that supplied the acid lime. Against the
   #060D0B page it showed as a faintly blue panel over a green-black ground. */
.hero-overlay{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(90deg,rgba(0,0,0,0.9) 0%,rgba(0,0,0,0.5) 25%,rgba(0,0,0,0.1) 50%,rgba(0,0,0,0.5) 75%,rgba(0,0,0,0.9) 100%);
}
@media(max-width:900px){
  .hero-overlay{background:linear-gradient(180deg,rgba(0,0,0,0.95) 0%,rgba(0,0,0,0.7) 25%,rgba(0,0,0,0.2) 50%,rgba(0,0,0,0.7) 75%,rgba(0,0,0,0.95) 100%);}
}

/* Eyebrow: sentence case, no dot, no acid green. ALL-CAPS mono labels with a
   coloured bullet in front of them are the single most templated element on
   the modern marketing page, so this keeps the mono and drops the shouting. */
.hero-eyebrow{font-family:var(--font-mono);font-size:0.78rem;letter-spacing:0.02em;color:var(--muted);margin:0 0 20px;font-weight:500;}
/* .hero-title / .hero-note are the classes index.php's rewritten hero uses.
   The title inherits .hero h1 above; this only sets the measure, so a two-line
   headline breaks where the <br> says it does and not one word earlier. */
.hero-title{max-width:16em;text-wrap:balance;}
.hero-note{font-family:var(--font-mono);font-size:0.8rem;line-height:1.6;color:var(--muted);margin:24px 0 0;padding-top:18px;border-top:1px solid var(--border);max-width:44ch;}
.hero-actions{display:flex;gap:14px;flex-wrap:wrap;margin-top:32px;}
.hero-stats{display:flex;gap:36px;margin-top:44px;flex-wrap:wrap;}
.hero-stats div strong{display:block;font-family:var(--font-display);font-size:1.9rem;font-weight:800;color:var(--primary);}
.hero-stats div span{font-size:0.85rem;color:var(--gray);}
/* CC-BY credit for the robot model, printed in includes/footer.php wherever
   the scene mounts. Small, but it has to stay legible: the licence requires
   the attribution be reasonable to the medium, not merely present. */
.model-credit{font-family:var(--font-mono);font-size:0.72rem;line-height:1.7;color:var(--muted);margin:28px 0 0;max-width:70ch;}
.model-credit a{color:var(--muted);text-decoration:underline;text-underline-offset:2px;}
.model-credit a:hover,.model-credit a:focus-visible{color:var(--text);}
@media(max-width:768px){.hero{min-height:auto;padding:56px 0 72px;}.hero-text-col{max-width:100%;}}

/* Grids */
.grid-2{display:grid;grid-template-columns:repeat(2,1fr);gap:28px;}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:28px;}
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;}
@media(max-width:900px){.grid-2,.grid-3,.grid-4{grid-template-columns:repeat(2,1fr);}}
@media(max-width:560px){.grid-2,.grid-3,.grid-4{grid-template-columns:1fr;}}

/* Pillar cards */
.pillar-card{padding:32px 28px;}

/* Pillar cards overlap the hero's bottom edge. Normal document flow --
   the section right after the hero has no other content in the way, so a
   simple negative margin pulls the cards up cleanly with no guesswork
   about heading heights and no leftover reserved gap below. */
.pillar-section-wrap{padding-top:0;}
.pillar-overlap-hero{position:relative;z-index:3;margin-top:-90px;}
@media(max-width:900px){.pillar-overlap-hero{margin-top:-60px;}}
@media(max-width:540px){.pillar-overlap-hero{margin-top:-40px;}}
/* Was var(--accent), the copper, at 0.78rem on a .pillar-card -- 3.25:1. Gold at
   5.49:1. Same change as .leader-role and .card-info-list .info-label below: all
   three were small copper labels sitting on a card. */
.pillar-card .num{font-family:var(--font-mono);font-size:0.78rem;color:var(--primary);font-weight:700;}
/* Only `.pillar-card .icon-badge` was ever declared, so the one `.icon-badge` on
   the site that is not inside a pillar card -- the tick on order-confirmation.php,
   which is the first thing a customer sees after paying -- had no rule at all: no
   width, no height, no radius. Its `<svg viewBox="0 0 24 24">` carries no width
   or height either, so it fell back to the SVG default of 300x150 and the badge
   rendered as a wide gradient slab. This base rule sets only properties the
   scoped rule below also sets, so the pillar cards are untouched by it. */
.icon-badge{width:52px;height:52px;border-radius:var(--radius-m);display:flex;align-items:center;justify-content:center;background:var(--surface-2);border:1px solid var(--glass-border);margin-bottom:16px;color:var(--primary);}
.icon-badge svg{width:24px;height:24px;stroke:currentColor;}
.pillar-card .icon-badge{width:52px;height:52px;border-radius:14px;display:flex;align-items:center;justify-content:center;background:var(--surface-2);border:1px solid var(--glass-border);margin-bottom:16px;color:var(--primary);}
.pillar-card .icon-badge svg{width:24px;height:24px;stroke:currentColor;}

/* Product cards */
.product-card{display:flex;flex-direction:column;overflow:hidden;position:relative;}
.product-card .thumb,.thumb{position:relative;aspect-ratio:4/3;background:var(--surface-2);overflow:hidden;border-radius:var(--radius-m) var(--radius-m) 0 0;}
.product-card .thumb img{width:100%;height:100%;object-fit:cover;transition:transform 0.4s ease;padding:14px;box-sizing:border-box;}
.product-card:hover .thumb img{transform:scale(1.04);}
.product-card .actions{display:flex;gap:8px;padding:0 20px 20px;}

/* Floating price badge over the image zone.
   Was white on gold (2.6:1) with a 14px coloured glow beneath it. The glow was
   the old orange until a moment ago and would only have become a gold halo
   around a gold chip; a badge sitting on a photo needs to be separated from it,
   which a neutral drop shadow does without lighting anything up. */
.card-price-badge{
  position:absolute;top:14px;right:14px;z-index:2;
  background:var(--primary);color:var(--bg);
  font-family:var(--font-mono);font-weight:700;font-size:0.85rem;
  padding:6px 14px;border-radius:var(--radius-m);
  box-shadow:0 2px 8px rgba(0,0,0,0.45);
}

/* Bold uppercase product title block */
.card-title-block{padding:18px 20px 0;}
.card-title-block h3{
  font-family:var(--font-display);font-weight:800;font-style:normal;
  font-size:1.05rem;text-transform:uppercase;letter-spacing:0.01em;
  margin:0 0 6px;color:var(--text);line-height:1.2;
}
.card-desc{padding:0 20px;font-size:0.86rem;color:var(--gray);margin:0 0 10px;line-height:1.5;}

/* Rating + compact info row, side by side like the reference */
.card-meta-row{
  display:flex;align-items:flex-start;justify-content:space-between;gap:14px;
  padding:0 20px 14px;
}
.card-meta-row .card-rating{display:flex;gap:2px;color:var(--yellow);flex-shrink:0;}
.card-meta-row .card-rating svg{width:14px;height:14px;}
.card-info-list{
  display:flex;flex-direction:column;gap:6px;
  border-left:2px solid var(--glass-border-hover);padding-left:12px;flex:1;
}
.card-info-list .info-item{display:flex;flex-direction:column;line-height:1.3;}
/* 0.62rem at weight 800 is the smallest type on the site, and it was copper at
   3.25:1 on the card. emods.css:504 forces var(--emods-gold) over the top of it,
   which is the same gold this now sets -- so the value here has been dead as well as
   wrong, and the two sheets agree for the first time. */
.card-info-list .info-label{font-size:0.62rem;font-weight:800;text-transform:uppercase;letter-spacing:0.05em;color:var(--primary);}
.card-info-list .info-value{font-size:0.76rem;color:var(--gray);}

.card-cart-btn{margin:0 20px 20px;}
.product-actions{display:flex;flex-direction:column;gap:14px;}
.product-actions-row{display:flex;align-items:stretch;gap:10px;flex-wrap:wrap;}
.product-actions-row .btn-primary{flex:1;min-width:160px;}
.product-actions-row .qty-stepper,.product-actions-row .btn{height:48px;}
.product-actions-row .wishlist-btn{height:48px;width:48px;}
/* The two rules below used to add `box-shadow:0 4px 16px rgba(37,211,102,0.28)` and
   a 24px version on hover -- a brand-green halo under a green button, which is the
   glow pattern deglow.mjs was written to remove and missed because it only looked
   for the palette's own colours. The green fill stays: a WhatsApp button being
   WhatsApp green is recognition, not decoration, and it is the one place on the site
   where an outside brand's colour earns its keep. The halo does not stay, because
   no other button on the site casts one. With the shadow gone the `:hover` rule had
   nothing left in it -- the darkened green is already set by `.btn-whatsapp:hover` in
   the Buttons block -- so it is gone too. */
.product-actions .btn-whatsapp{margin-top:2px;}
.product-title{font-size:clamp(1.5rem,3vw,2.2rem)!important;font-style:italic;}
.price{font-weight:800;font-size:1.2rem;color:var(--text);}
.price-row{display:flex;align-items:baseline;gap:10px;margin:10px 0;}
.price-sale{font-weight:800;font-size:1.3rem;color:var(--primary);}
.price-original{font-size:0.9rem;color:var(--gray);text-decoration:line-through;}
/* Gold #C89B3C behind white text is 2.6:1. Ink on the same gold is 7.7:1. */
.sale-badge{background:var(--primary);color:var(--bg);font-size:0.68rem;font-weight:800;padding:3px 9px;border-radius:var(--radius-m);}
.badge-trust{font-size:0.72rem;color:var(--success-text);font-weight:700;}

/* Tags
   Every colour in this block was chosen while the site had a cream background,
   and none of them was revisited when it went dark. Three were unreadable:
   #9C7B14 on its amber tint measures 3.76:1 and #8A6810 is darker still, both
   under AA at 0.68rem, and .tag-project put #B5405A on a pink wash. Three more
   were off-palette entirely -- rgba(214,83,109) is a rose from a palette that
   no longer exists, and .tag-cyan was painting itself with it, so the class
   name described neither its colour nor anything else.

   Rather than hand-tune nine foreground colours against nine backgrounds, the
   label is bone in all of them (about 15:1 on every tint here) and the hue
   moves to a 2px left edge plus the tint behind it. Each variant now sets two
   properties, both drawn from the four-hue palette, and no combination can
   drift into an unreadable pair. */
.tag{display:inline-block;font-size:0.68rem;font-weight:800;letter-spacing:0.04em;text-transform:uppercase;padding:5px 11px 5px 9px;border-radius:var(--radius-m);color:var(--text);border-left:2px solid transparent;}
.tag-kit,.tag-kind-kit{background:rgba(180,101,58,0.16);border-left-color:var(--secondary);}
.tag-iot,.tag-kind-iot{background:rgba(200,155,60,0.16);border-left-color:var(--primary);}
.tag-store,.tag-kind-store{background:rgba(200,155,60,0.10);border-left-color:var(--primary);}
.tag-project{background:rgba(90,158,111,0.14);border-left-color:var(--success);}
.tag-bundle,.tag-amber{background:rgba(200,155,60,0.18);border-left-color:var(--primary);}
/* Kept because templates still carry the class; it is copper, like .tag-kit,
   because there is no cyan in this palette and there has not been for a while. */
.tag-cyan{background:rgba(180,101,58,0.12);border-left-color:var(--secondary);}
.tag-green{background:rgba(90,158,111,0.14);border-left-color:var(--success);}
.tag-red{background:rgba(194,80,60,0.14);border-left-color:var(--error);}
/* The three promo tags are the loud ones: solid fills rather than tints, so
   they read as a stamp on the card instead of a category label. */
.tag-promo-hot{background:var(--primary);color:var(--bg);border-left-color:var(--primary);}
/* Ink here too, not bone: bone on copper is 3.50:1, and this is 0.68rem
   uppercase. Ink on the same copper is 4.54:1, which clears AA by a hair. */
.tag-promo-limited{background:var(--secondary);color:var(--bg);border-left-color:var(--secondary);}
.tag-promo-bestseller{background:var(--ink);color:var(--bg);border-left-color:var(--ink);}

/* Gallery */
.gallery-wrap{position:relative;}
.gallery-main{border-radius:var(--radius-l);overflow:hidden;background:var(--surface-2);border:1px solid var(--glass-border);aspect-ratio:1/1;}
.gallery-main img{width:100%;height:100%;object-fit:cover;}
.gallery-thumbs{display:flex;gap:10px;margin-top:14px;}
.gallery-thumbs img{width:64px;height:64px;object-fit:cover;border-radius:10px;cursor:pointer;border:2px solid transparent;opacity:0.6;transition:all 0.18s ease;}
.gallery-thumbs img.active{opacity:1;border-color:var(--primary);}
.gallery-arrow{position:absolute;top:50%;transform:translateY(-50%);width:40px;height:40px;border-radius:50%;background:var(--surface);border:1px solid var(--glass-border);display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:var(--shadow-card);z-index:2;color:var(--text);}
.gallery-arrow:hover{background:var(--ink);color:var(--bg);}
.gallery-arrow.prev{left:-18px;}
.gallery-arrow.next{right:-18px;}
.carousel-arrow{width:38px;height:38px;border-radius:50%;background:var(--surface);border:1px solid var(--glass-border);display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--text);}
.carousel-arrow:hover{background:var(--ink);color:var(--bg);}

/* Filters */
.filter-bar{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:32px;}
.filter-chip{padding:9px 18px;border-radius:var(--radius-m);border:1.5px solid var(--glass-border-hover);background:var(--surface);color:var(--text);font-size:0.85rem;font-weight:700;cursor:pointer;transition:all 0.18s ease;}
.filter-chip.active,.filter-chip:hover{background:var(--ink);color:var(--bg);border-color:var(--text);}

/* Forms */
.form-card{padding:32px;}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;}
@media(max-width:640px){.form-grid{grid-template-columns:1fr;}}
.field{margin-bottom:18px;}
.field.full{grid-column:1/-1;}
label{display:block;font-size:0.84rem;font-weight:700;color:var(--text);margin-bottom:6px;}
input,select,textarea{width:100%;padding:12px 15px;border:1.5px solid var(--glass-border-hover);border-radius:var(--radius-s);font-family:var(--font-body);font-size:0.92rem;background:var(--surface);color:var(--text);transition:border-color 0.15s ease,box-shadow 0.15s ease;}
input::placeholder,textarea::placeholder{color:var(--gray);}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px rgba(200, 155, 60,0.1);}
a:focus-visible,button:focus-visible,.btn:focus-visible,input[type="checkbox"]:focus-visible,input[type="radio"]:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--primary);outline-offset:2px;}
select option{background:var(--surface);color:var(--text);}
textarea{resize:vertical;min-height:110px;}
.help-text{font-size:0.78rem;color:var(--gray);margin-top:5px;}
/* The tints were rgba(31,138,90) and rgba(214,48,74) -- the green and red of
   the palette two versions ago, not --success #5A9E6F and --error #C2503C. The
   error text was the bigger problem: #C2503C on its own dark wash is 3.2:1,
   and an error message is the last thing on a page that should be hard to read.
   Bone text on the tint is about 14:1, with the hue carried by a solid left
   edge -- the same arrangement as .tag and .status-pill. */
.alert{padding:14px 18px;border-radius:var(--radius-s);margin-bottom:18px;font-size:0.9rem;font-weight:600;color:var(--text);border:1px solid var(--border);border-left-width:3px;background:var(--surface);}
/* Each variant used to set `background:rgba(<hue>,0.12)` on its own, which
   replaces the base fill rather than layering over it -- one background-color
   property cannot hold two colours. That left every alert on the site a 12% tint
   with nothing behind it, and emods.css:1159 makes .section/.hero transparent so
   the robot shows through: a login failure, a checkout error or an LMS lock
   message was 88% live WebGL scene with type on top. Alerts are also the one
   component that only ever appears when something has gone wrong, so it is the
   worst place on the site for text to become unreadable.
   The two-layer form below keeps the 12% rgba visible in the source -- so the
   link back to --success/--error/--warning/--secondary stays legible to whoever
   edits this next -- while the trailing var(--surface) closes the stack. A flat
   linear-gradient is the standard way to spell "tint over colour" in one
   shorthand: the gradient is the top layer, the colour is the bottom. Bone text
   lands between 9.4:1 and 10.5:1 on all four. */
.alert-success{background:linear-gradient(rgba(90,158,111,0.12),rgba(90,158,111,0.12)),var(--surface);border-color:rgba(90,158,111,0.3);border-left-color:var(--success);}
.alert-error{background:linear-gradient(rgba(194,80,60,0.12),rgba(194,80,60,0.12)),var(--surface);border-color:rgba(194,80,60,0.3);border-left-color:var(--error);}
/* Neither of these two existed. `.alert-info` was already on the empty-results
   message in kits.php and store.php, where it fell through to the plain .alert
   above -- harmless but pointless. `.alert-warning` was the missing one: two
   templates wanted a warning and reached for an inline style to get it, which
   reinstated rgba(239,177,29) and #8A6408 -- an amber and a dark brown from the
   palette before this one, the brown being unreadable on a dark ground. */
.alert-warning{background:linear-gradient(rgba(200,155,60,0.12),rgba(200,155,60,0.12)),var(--surface);border-color:rgba(200,155,60,0.3);border-left-color:var(--warning);}
.alert-info{background:linear-gradient(rgba(180,101,58,0.12),rgba(180,101,58,0.12)),var(--surface);border-color:rgba(180,101,58,0.3);border-left-color:var(--secondary);}
/* forgot-password.php and reset-password.php both write `class="alert alert-danger"`,
   and no stylesheet has ever defined that class -- so the one message a user sees
   when a reset link is invalid or expired rendered with the base .alert fill and a
   grey hairline down its left edge, giving no signal that anything had gone wrong.
   Aliased to the error variant rather than renamed in the two templates, because
   `alert-danger` is the Bootstrap spelling and is the name someone will reach for
   again. */
.alert-danger{background:linear-gradient(rgba(194,80,60,0.12),rgba(194,80,60,0.12)),var(--surface);border-color:rgba(194,80,60,0.3);border-left-color:var(--error);}
.auth-divider{display:flex;align-items:center;gap:12px;margin:20px 0;color:var(--gray);font-size:0.82rem;}
.auth-divider::before,.auth-divider::after{content:'';flex:1;height:1px;background:var(--glass-border);}
.google-signin-wrap{display:flex;justify-content:center;margin:14px 0;}
.auth-section{padding:60px 0;}

/* Cart */
.cart-table{width:100%;border-collapse:collapse;}
.cart-table th{text-align:left;font-size:0.72rem;text-transform:uppercase;letter-spacing:0.06em;color:var(--gray);padding:12px;border-bottom:1.5px solid var(--glass-border-hover);font-weight:700;}
.cart-table td{padding:16px 12px;border-bottom:1px solid var(--glass-border);vertical-align:middle;}
.cart-item-name{font-weight:700;color:var(--text);}
.qty-stepper{display:inline-flex;align-items:center;border:1.5px solid var(--glass-border-hover);border-radius:var(--radius-m);overflow:hidden;height:44px;}
.qty-stepper button{background:var(--surface-2);border:none;width:36px;height:100%;cursor:pointer;font-size:1.05rem;color:var(--text);flex-shrink:0;}
.qty-stepper input{width:42px;border:none;text-align:center;padding:0;height:100%;color:var(--text);font-weight:600;}
.cart-summary{padding:28px;}
.row{display:flex;justify-content:space-between;margin-bottom:11px;font-size:0.94rem;color:var(--text);}
.row.total{font-weight:800;font-size:1.2rem;border-top:1.5px solid var(--glass-border-hover);padding-top:14px;margin-top:14px;}
/* 0.82rem bold is small text, so this needs the lifted red, not the fill red. */
.remove-link{color:var(--error-text);font-size:0.82rem;font-weight:700;}
.empty-state{text-align:center;padding:70px 20px;color:var(--gray);}
.empty-state svg{width:64px;height:64px;stroke:var(--glass-border-hover);margin:0 auto 20px;display:block;}
.empty-state h3{color:var(--text);margin-bottom:8px;}
.cart-layout{display:grid;grid-template-columns:2fr 1fr;align-items:flex-start;gap:24px;}
.checkout-layout{display:grid;grid-template-columns:1.4fr 1fr;align-items:flex-start;gap:24px;}
@media(max-width:900px){.cart-layout,.checkout-layout{grid-template-columns:1fr;}}

/* Order tracker */
.order-tracker{display:flex;justify-content:space-between;margin:24px 0;}
.track-step{flex:1;text-align:center;position:relative;font-size:0.78rem;color:var(--gray);font-weight:600;}
.track-dot{width:14px;height:14px;border-radius:50%;background:var(--surface-2);border:2px solid var(--glass-border-hover);margin:0 auto 8px;}
.track-step.done .track-dot{background:var(--primary);border-color:var(--primary);}
.track-step.done{color:var(--primary);}

/* Account tabs */
.account-tabs{display:flex;gap:6px;border-bottom:1.5px solid var(--glass-border);margin-bottom:28px;}
.account-tabs a{padding:12px 18px;font-size:0.9rem;font-weight:700;color:var(--gray);border-bottom:2px solid transparent;margin-bottom:-1.5px;}
.account-tabs a.active{color:var(--primary);border-color:var(--primary);}

/* Leader / team */
.leader-card{padding:28px;text-align:center;}
.leader-photo{width:96px;height:96px;border-radius:50%;margin:0 auto 16px;background:var(--surface-2);border:1px solid var(--glass-border);}
/* Copper at 0.78rem on a .leader-card -- 3.25:1, and a person's job title is not
   decoration. Gold, 5.49:1. */
.leader-role{font-size:0.78rem;color:var(--primary);font-weight:700;text-transform:uppercase;letter-spacing:0.05em;}

/* Timeline */
.timeline{position:relative;padding-left:28px;border-left:2px solid var(--glass-border-hover);}
.timeline-item{position:relative;padding-bottom:28px;}
.timeline-item::before{content:'';position:absolute;left:-34px;top:2px;width:12px;height:12px;border-radius:50%;background:var(--primary);}

/* FAQ */
.faq-group{margin-bottom:20px;}
.faq-item{overflow:hidden;}
.faq-question{padding:18px 22px;display:flex;justify-content:space-between;align-items:center;cursor:pointer;font-weight:700;}
.faq-answer{padding:0 22px;max-height:0;overflow:hidden;transition:max-height 0.3s ease;}
.faq-item.open .faq-answer{padding:0 22px 20px;max-height:600px;}
.chev{transition:transform 0.2s ease;color:var(--gray);}
.faq-item.open .chev{transform:rotate(180deg);color:var(--primary);}

/* Product tabs */
.product-tabs{display:flex;gap:4px;border-bottom:1.5px solid var(--glass-border);margin-bottom:28px;overflow-x:auto;}
.product-tab-btn{padding:12px 20px;font-weight:700;font-size:0.88rem;color:var(--gray);background:none;border:none;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1.5px;white-space:nowrap;}
.product-tab-btn.active{color:var(--primary);border-color:var(--primary);}
.product-tab-panel{display:none;}
.product-tab-panel.active{display:block;}

/* Reviews / stars */
.star-rating{color:var(--yellow);display:inline-flex;gap:2px;}
.star-input{display:inline-flex;gap:4px;}
.review-card{padding:18px 0;border-bottom:1px solid var(--glass-border);}
/* --c-blue is an alias for --accent, which this file re-declares as the copper
   #B4653A; white on it is 4.32:1, just under AA. The active state of a "was this
   review helpful" button is a small label, so it takes ink on the copper at
   4.54:1. Spelled --secondary rather than --c-blue because that is the token
   that actually holds this hue. */
.vote-btn.active{background:var(--secondary);color:var(--bg);border-color:var(--secondary);}
.reviewer{font-weight:700;color:var(--text);}
.review-date{font-size:0.78rem;color:var(--gray);}

/* Related products carousel */
.related-products-section{margin-top:48px;}
.related-carousel-wrap{position:relative;}
.related-carousel{display:flex;gap:20px;overflow-x:auto;scroll-behavior:smooth;scrollbar-width:none;}
.related-carousel::-webkit-scrollbar{display:none;}
.related-card{flex:0 0 240px;}

/* Marquee
   Both of the declarations that used to be here -- `background:var(--ink)` and
   `color:#fff` -- were dead: emods.css sets both on .marquee-bar with
   !important (a gold-tinted dark bar with bone text). They are dropped rather
   than corrected, because leaving a plausible-looking dead value invites the
   next person to edit it and wonder why nothing moves.
   Note also the @keyframes below: an infinite animation, caught by the blanket
   reduced-motion rule at the end of this file which caps iteration count at 1. */
.marquee-bar{overflow:hidden;white-space:nowrap;padding:10px 0;}
.marquee-track{display:inline-flex;gap:48px;animation:marquee 26s linear infinite;}
.marquee-item{font-size:0.82rem;font-weight:600;display:inline-flex;align-items:center;gap:10px;}
@keyframes marquee{from{transform:translateX(0);}to{transform:translateX(-50%);}}

/* Footer
   `background:var(--ink)` was dead here too -- emods.css:1134 forces
   `.site-footer{background:transparent!important}` so the 3D layer shows
   through -- and while --ink was near-black it also described the opposite of
   what now renders. The text colour moves to the palette's own muted token
   instead of a raw translucent white. */
.site-footer{color:var(--muted);padding:64px 0 28px;margin-top:60px;}
.footer-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:32px;margin-bottom:40px;}
@media(max-width:900px){.footer-grid{grid-template-columns:1fr 1fr;}}
@media(max-width:560px){.footer-grid{grid-template-columns:1fr;}}
/* Both of these were #fff. Nothing else on the site uses pure white as a text
   colour -- even --white is declared as the bone #EDE7D9 -- so the footer column
   headings and the hovered legal links were the only cold type on a warm page. */
.footer-grid h4{color:var(--text);font-size:0.95rem;margin-bottom:16px;}
.footer-grid a{color:var(--muted);}
.footer-grid a:hover{color:var(--primary);}
.footer-grid .brand img{filter:brightness(0);}
.footer-bottom{border-top:1px solid var(--border);padding-top:22px;display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;font-size:0.82rem;}
.footer-legal-links{display:flex;gap:16px;}
.footer-legal-links a:hover{color:var(--text);}
.legal-content h2{font-size:1.4rem;margin-top:32px;}
.legal-content p,.legal-content li{color:var(--gray);}

/* Misc */
.flex-between{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;}
.muted{color:var(--gray);}
.spacer-s{height:16px;}.spacer-m{height:32px;}.spacer-l{height:64px;}
.breadcrumb{font-size:0.82rem;color:var(--gray);margin-bottom:20px;}
.breadcrumb a:hover{color:var(--primary);}
.reveal{opacity:0;transform:translateY(20px);transition:opacity 0.6s ease,transform 0.6s ease;}
.reveal.in{opacity:1;transform:translateY(0);}
@media(prefers-reduced-motion:reduce){
  /* Without this the fade-up never resolves for anyone who asked for stillness:
     .reveal sets opacity:0 up front and only assets/js/animations.js adds .in,
     so suppressing the transition alone is not enough -- the content has to be
     visible whether or not the observer ever fires. */
  .reveal{opacity:1;transform:none;transition:none;}
}

/* Homepage: "What are you looking to do?" (#paths).
   Deliberately not .glass-card. Three filled, shadowed, rounded panels side by
   side is the shape every generated landing page arrives in; these are plain
   bordered columns that gain a left rule on hover instead. */
.path-grid{gap:0;border-top:1px solid var(--border);}
.path-card{display:block;padding:30px 28px 28px;text-decoration:none;border-right:1px solid var(--border);border-bottom:1px solid var(--border);transition:background 0.2s ease;}
.path-card:first-child{border-left:1px solid var(--border);}
.path-card:hover{background:var(--surface-2);text-decoration:none;}
.path-icon{display:block;color:var(--primary);margin-bottom:26px;}
.path-card h3{font-size:1.1rem;margin:0 0 7px;letter-spacing:-0.01em;}
.path-meta{font-family:var(--font-mono);font-size:0.76rem;line-height:1.5;color:var(--muted);margin:0 0 20px;}
.path-cue{display:inline-flex;align-items:center;gap:6px;font-family:var(--font-mono);font-size:0.74rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--muted);}
.path-card:hover .path-cue{color:var(--primary);}
@media(max-width:900px){
  .path-card{border-left:1px solid var(--border);}
}

/* Homepage: "How we check hardware" (#why).
   A numbered list, because it is a sequence and the section rail in
   includes/header.php announces it as one. */
/* No background here. The element is <section class="section check-band">, and
   emods.css -- which loads after this file -- sets `.section, .section-alt,
   .hero, .site-wrapper, .site-footer { background: transparent !important }` so
   the 3D robot stays visible through the page. A background on this rule could
   not win, and would not be wanted if it could: a solid band across the middle
   of the homepage is exactly what would occlude the model. The two hairlines
   separate the band on their own. */
.check-band{border-top:1px solid var(--border);border-bottom:1px solid var(--border);}
.check-list{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:40px;}
.check-step{padding-top:20px;border-top:2px solid var(--primary);}
.check-num{display:block;font-family:var(--font-mono);font-size:0.74rem;letter-spacing:0.16em;color:var(--primary);margin-bottom:14px;}
.check-step h3{font-size:1.12rem;margin:0 0 10px;letter-spacing:-0.01em;}
.check-step p{margin:0;font-size:0.94rem;line-height:1.7;color:var(--muted);}
@media(max-width:900px){
  .check-list{grid-template-columns:1fr;gap:28px;}
}
.thumb-sm{width:44px;height:44px;object-fit:cover;border-radius:8px;}
.thumb-strip{display:flex;gap:8px;flex-wrap:wrap;}
.thumb-item{position:relative;}
.remove-x{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;background:var(--c-error);color:#fff;font-size:11px;line-height:18px;text-align:center;cursor:pointer;}
.frame{border:1px solid var(--glass-border);border-radius:var(--radius-m);overflow:hidden;}

/* Status pills */
/* Same treatment as .tag above, and for the same reason: .status-pending and
   .status-reviewed were #8A6810 on an amber wash, which is a dark brown on a
   near-black page. These appear on order history and application status, where
   being unable to read the word is the whole failure. Bone label, hue on the
   left edge. */
.status-pill{font-size:0.7rem;font-weight:800;padding:4px 10px 4px 8px;border-radius:var(--radius-m);text-transform:uppercase;letter-spacing:0.03em;color:var(--text);border-left:2px solid transparent;}
.status-new,.status-open{background:rgba(180,101,58,0.16);border-left-color:var(--secondary);}
.status-pending{background:rgba(200,155,60,0.18);border-left-color:var(--primary);}
.status-confirmed,.status-delivered,.status-resolved{background:rgba(90,158,111,0.14);border-left-color:var(--success);}
.status-cancelled,.status-rejected,.status-terminated{background:rgba(194,80,60,0.14);border-left-color:var(--error);}
.status-shipped,.status-shortlisted{background:rgba(200,155,60,0.10);border-left-color:var(--primary);}
.status-reviewed{background:rgba(180,101,58,0.12);border-left-color:var(--secondary);}

/* `.wa-float` -- a 56px fixed circle bottom-right carrying
   `box-shadow:0 8px 24px rgba(37,211,102,0.4)` -- used to be declared here, and
   emods.css:795 re-declared the same rule with a second layer,
   `0 0 12px rgba(37,211,102,0.2)`: a zero-offset halo, i.e. the last literal glow
   left on the site. Both are gone, because the selector is dead -- grepping every
   .php, .js and .html for `wa-float` returns nothing, so no page has ever rendered
   the element. Two sheets were maintaining paint for a floating button that does not
   exist. The real WhatsApp affordance is `.btn-whatsapp`, in the Buttons block above. */

/* =========================================================================
   HOMEPAGE DISTINCTIVE SECTIONS (Breaking templated 3-across rhythm)
   ========================================================================= */

/* #kits: Flagship starter + Progression ladder */
.kits-showcase-grid{display:grid;grid-template-columns:1.35fr 1fr;gap:24px;align-items:stretch;}
.kit-flagship-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-m);display:flex;flex-direction:column;}
.kit-flagship-thumb{aspect-ratio:16/10;}
.kit-flagship-badge{position:absolute;top:12px;left:12px;background:var(--primary);color:var(--bg);font-family:var(--font-mono);font-size:0.68rem;font-weight:800;letter-spacing:0.06em;text-transform:uppercase;padding:3px 8px;border-radius:var(--radius-m);}
.kit-flagship-info{padding:24px;display:flex;flex-direction:column;flex:1;}
.kit-hardware-spec{margin:16px 0;padding:14px 16px;background:var(--surface-2);border-radius:var(--radius-m);border-left:2px solid var(--primary);}
.kit-hardware-spec .spec-label{display:block;font-family:var(--font-mono);font-size:0.72rem;font-weight:700;letter-spacing:0.06em;text-transform:uppercase;color:var(--primary);margin-bottom:8px;}
.spec-items{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px;}
.spec-items li span{font-size:0.84rem;color:var(--text);line-height:1.4;}

.kits-progression-col{display:flex;flex-direction:column;gap:16px;}
.progression-head{padding:4px 0 6px;}
.progression-sub{margin:0;font-size:0.84rem;color:var(--muted);}
.kit-ladder-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-m);display:flex;flex-direction:row;overflow:hidden;flex:1;}
.kit-ladder-thumb{width:140px;aspect-ratio:auto;flex-shrink:0;}
.kit-ladder-body{padding:16px 18px;display:flex;flex-direction:column;flex:1;}

@media(max-width:900px){
  .kits-showcase-grid{grid-template-columns:1fr;gap:20px;}
  .kit-ladder-card{flex-direction:column;}
  .kit-ladder-thumb{width:100%;aspect-ratio:16/9;}
}

/* #iot: Engineering Architecture + Hardware Grid */
.iot-showcase-grid{display:grid;grid-template-columns:1.15fr 1fr;gap:24px;align-items:stretch;}
.iot-arch-panel{background:linear-gradient(rgba(200,155,60,0.03),rgba(200,155,60,0.03)),var(--surface);border:1px solid var(--border);border-radius:var(--radius-m);padding:30px 26px;display:flex;flex-direction:column;}
.iot-arch-title{font-size:1.35rem;letter-spacing:-0.02em;margin:8px 0 10px;color:var(--text);}
.iot-arch-intro{font-size:0.9rem;line-height:1.6;color:var(--muted);margin-bottom:20px;}
.iot-arch-specs{list-style:none;margin:0 0 24px;padding:0;display:flex;flex-direction:column;gap:16px;flex:1;}
.iot-arch-specs li{display:flex;gap:14px;align-items:flex-start;}
.iot-arch-icon{width:32px;height:32px;border-radius:var(--radius-m);background:var(--surface-2);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:1rem;}
.iot-arch-specs strong{display:block;font-size:0.92rem;color:var(--text);margin-bottom:2px;}
.iot-arch-specs p{margin:0;font-size:0.84rem;line-height:1.5;color:var(--muted);}
.iot-arch-action{margin-top:auto;}

.iot-products-col{display:flex;flex-direction:column;gap:16px;}
.iot-product-row{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-m);display:flex;flex-direction:row;overflow:hidden;flex:1;}
.iot-row-thumb{width:140px;aspect-ratio:auto;flex-shrink:0;}
.iot-row-content{padding:16px 18px;display:flex;flex-direction:column;flex:1;}

@media(max-width:900px){
  .iot-showcase-grid{grid-template-columns:1fr;gap:20px;}
  .iot-product-row{flex-direction:column;}
  .iot-row-thumb{width:100%;aspect-ratio:16/9;}
}

/* #community: Spotlight + Companion */
.community-spotlight-grid{display:grid;grid-template-columns:1.3fr 1fr;gap:24px;align-items:stretch;}
.community-lead-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-m);display:flex;flex-direction:column;text-decoration:none;}
.community-lead-img{position:relative;height:240px;overflow:hidden;background:var(--surface-2);}
.community-lead-img img{width:100%;height:100%;object-fit:cover;transition:transform 0.4s ease;}
.community-lead-card:hover .community-lead-img img{transform:scale(1.03);}
.community-lead-badge{position:absolute;top:12px;left:12px;background:var(--primary);color:var(--bg);font-family:var(--font-mono);font-size:0.68rem;font-weight:800;letter-spacing:0.06em;text-transform:uppercase;padding:3px 8px;border-radius:var(--radius-m);}

.community-companion-col{display:flex;flex-direction:column;gap:16px;}
.community-side-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-m);display:flex;flex-direction:row;overflow:hidden;text-decoration:none;flex:1;}
.community-side-img{width:130px;overflow:hidden;background:var(--surface-2);flex-shrink:0;}
.community-side-img img{width:100%;height:100%;object-fit:cover;transition:transform 0.4s ease;}
.community-side-card:hover .community-side-img img{transform:scale(1.04);}

@media(max-width:900px){
  .community-spotlight-grid{grid-template-columns:1fr;gap:20px;}
  .community-side-card{flex-direction:column;}
  .community-side-img{width:100%;height:160px;}
}

/* =========================================================================
   RESPONSIVE
   ========================================================================= */
@media(max-width:640px){
  .glass-card{padding:22px;}
  .hero{padding:40px 0 64px;}
  .footer-grid{gap:24px;}
}

/* =========================================================================
   Product Detail Sticky Layout
   ========================================================================= */
@media (min-width: 900px) {
  .sticky-product-details {
    position: sticky;
    top: 100px;
    height: max-content;
  }
}

/* =========================================================================
   Toast Notifications
   ========================================================================= */
#toast-container {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.toast {
  background: var(--surface);
  color: var(--text);
  padding: 16px 24px;
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-lift);
  border-left: 4px solid var(--primary);
  font-weight: 500;
  transform: translateX(120%);
  transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.toast.show {
  transform: translateX(0);
}
.toast.toast-success { border-left-color: var(--success); }
.toast.toast-error { border-left-color: var(--error); }
.toast.toast-warning { border-left-color: var(--warning); }

/* =========================================================================
   Skeleton Loading System
   ========================================================================= */
.skeleton {
  background: linear-gradient(90deg, var(--bg-alt) 25%, var(--surface) 50%, var(--bg-alt) 75%);
  background-size: 200% 100%;
  animation: skeleton-loading 1.5s infinite;
  border-radius: var(--radius-s);
}
.skeleton-text {
  height: 1em;
  margin-bottom: 0.5em;
  width: 100%;
}
.skeleton-text:last-child {
  width: 80%;
  margin-bottom: 0;
}
.skeleton-image {
  width: 100%;
  height: 200px;
}
@keyframes skeleton-loading {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
#toast-container { position: fixed; bottom: 20px; right: 20px; z-index: 10000; display: flex; flex-direction: column; gap: 10px; pointer-events: none; }
#toast-container .toast { pointer-events: auto; }
.mobile-nav { z-index: 9999 !important; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}

/* Scroll Animations */
.reveal { opacity: 0; transform: translateY(40px); transition: all 0.8s cubic-bezier(0.16, 1, 0.3, 1); }
.reveal.active { opacity: 1; transform: translateY(0); }
.reveal.delay-1 { transition-delay: 0.1s; }
.reveal.delay-2 { transition-delay: 0.2s; }
.reveal.delay-3 { transition-delay: 0.3s; }
