:root {
  color-scheme: light;
  --ink: #14201d;
  --muted: #62716c;
  --line: #dfe7e2;
  --paper: #f7faf8;
  --panel: #ffffff;
  --accent: #03547f;
  --accent-dark: #03547f;
  --gold: #03547f;
  --sky: #d9edf5;
  --shadow: 0 18px 55px rgba(20, 32, 29, 0.12);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
}

/* The browser's own `[hidden] { display: none }` lives in the UA stylesheet,
   which any author rule outranks -- so a class that sets `display` on an
   element also carrying the `hidden` attribute silently un-hides it. That's
   what was drawing the empty second card under the warranty form:
   .warranty-check-result sets `display: flex`, which beat the `hidden` the
   markup ships with until the JS fills it in.

   `!important` is the standard fix (normalize.css does the same) and is
   what keeps `hidden` meaning hidden regardless of what a later rule says.
   Anything that needs to show must remove the attribute, which is exactly
   what warranty-check.js and ticket-create.js already do. */
[hidden] {
  display: none !important;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  color: var(--ink);
  background: var(--paper);
}

/* Homepage-only background -- pale mint/seafoam, matching the
   reference screenshot, scoped so it doesn't affect other pages. */
body.alt-bg {
  background: #e3e2ea;
}

/* Extend the same tone to every section on these pages that otherwise
   carries its own background (blue-tinted band/bar), so the page reads
   as one consistent color instead of alternating panels. The CTA band is
   left on its dark brand-blue background since it uses white text --
   swapping that would make the text unreadable. */
body.alt-bg .split-band {
  background: #e3e2ea;
}

body.alt-bg .usp-bar {
  background: #f5f5f7;
}

/* Nav bar -- same lavender tone as the rest of the page, kept translucent
   with its existing blur so it still reads as a frosted sticky header. */
body.alt-bg .site-header {
  background: rgba(227, 226, 234, 0.92);
}

/* Several product-detail pages wrap their whole page in a <main> with its
   own solid background (set independently of <body>), which otherwise
   paints over the body color entirely. Match those to the same tone so
   the page reads consistently instead of the <main> masking it. */
body.alt-bg .aio-page,
body.alt-bg .workstation-page,
body.alt-bg .peripherals-page,
body.alt-bg .keyboard-page,
body.alt-bg .monitor-page,
body.alt-bg .mouse-page {
  background: #e3e2ea;
}

/* Plain white/near-white sections -- safe direct swap, text on these was
   already dark ink so nothing else needs to change. */
body.alt-bg .aio-hero,
body.alt-bg .peripheral-picks-section,
body.alt-bg .contact-section,
body.alt-bg .pricing-section,
body.alt-bg .spec-band,
body.alt-bg .comparison-section,
body.alt-bg .workstation-hero {
  background: #e3e2ea;
}

/* Dark brand-blue spotlight/CTA-style sections (showcase, builder,
   compare table, and the keyboard/monitor/mouse CTA bands) -- these used
   white text on a dark background, so the text flips to dark ink/muted
   to stay readable on the lighter tone. Deeply-nested widget cards (the
   live configurator summary/price sidebar) are left on their dark card
   styling intentionally -- they read as a purposeful accent card on a
   light section, similar to a checkout summary. */
body.alt-bg .aio-showcase,
body.alt-bg .aio-builder-section,
body.alt-bg .workstation-showcase,
body.alt-bg .peripheral-compare-section,
body.alt-bg .keyboard-cta,
body.alt-bg .monitor-cta,
body.alt-bg .mouse-cta {
  background: #e3e2ea;
  color: var(--ink);
}

body.alt-bg .aio-showcase-copy > p:not(.eyebrow, .aio-showcase-price),
body.alt-bg .aio-builder-section .configurator-intro p,
body.alt-bg .peripheral-compare-intro p:not(.eyebrow),
body.alt-bg .peripheral-use-grid p {
  color: var(--muted);
}

body.alt-bg .aio-showcase .eyebrow,
body.alt-bg .aio-builder-section .eyebrow,
body.alt-bg .peripheral-compare-intro .eyebrow {
  color: var(--accent-dark);
}

body.alt-bg .peripheral-use-grid article {
  background: rgba(20, 32, 29, 0.05);
  border-color: rgba(20, 32, 29, 0.12);
}

body.alt-bg .monitor-cta .button.secondary,
body.alt-bg .mouse-cta .button.secondary {
  color: var(--accent-dark);
  background: transparent;
  border-color: rgba(20, 32, 29, 0.3);
}

/* "Need Help Choosing?" CTA band -- switching it to the same light tone
   means the white-on-dark-blue text needs to flip to dark-on-light so it
   stays readable. The button itself keeps its own solid accent
   background, so it still stands out fine against the lighter section. */
body.alt-bg .cta-band {
  background: #e3e2ea;
  color: var(--ink);
}

body.alt-bg .cta-band p,
body.alt-bg .cta-band .eyebrow {
  color: var(--muted);
}

a {
  color: inherit;
  text-decoration: none;
}

img {
  display: block;
  max-width: 100%;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 88px;
  padding: 14px clamp(18px, 4vw, 64px);
  background: rgba(247, 250, 248, 0.97);
  border-bottom: 1px solid var(--line);
  /* Forces the sticky header onto its own GPU-composited layer at all
     times (instead of only when Chrome decides it needs one). Sticky
     elements that DON'T already have their own layer are the ones prone
     to the "stale tile" ghosting bug -- as the element re-anchors during
     scroll, Chrome can reuse an old rasterized tile for a frame instead
     of repainting, which is what was showing page content bleeding
     through the header/dropdown. */
  transform: translateZ(0);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 1.18rem;
  font-weight: 800;
  letter-spacing: 0;
}

.brand-mark {
  display: block;
  width: 60px;
  height: 60px;
  border-radius: 0;
  box-shadow: 0 10px 22px rgba(3, 84, 127, 0.26);
  object-fit: contain;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  row-gap: 6px;
  align-items: center;
  gap: clamp(12px, 2vw, 28px);
  color: var(--muted);
  font-weight: 650;
}

.site-nav a {
  padding: 9px 0;
  border-bottom: 2px solid transparent;
}

.site-nav a:hover {
  color: var(--accent-dark);
}

.site-nav a.active {
  color: var(--accent-dark);
  border-bottom-color: var(--gold);
}

/* Hamburger toggle -- injected by mobile-nav.js and only ever shown under
   the 720px breakpoint (see the media query near the bottom of this file).
   Hidden here so it never appears on desktop even while the script is
   still loading. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  color: var(--accent-dark);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 8px;
  cursor: pointer;
}

.nav-toggle-bars {
  position: relative;
  display: block;
  width: 20px;
  height: 14px;
}

.nav-toggle-bars span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: transform 200ms ease, opacity 200ms ease;
}

.nav-toggle-bars span:nth-child(1) { top: 0; }
.nav-toggle-bars span:nth-child(2) { top: 6px; }
.nav-toggle-bars span:nth-child(3) { top: 12px; }

/* Open state -- the three bars collapse into an X. */
.site-header.nav-open .nav-toggle-bars span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}

.site-header.nav-open .nav-toggle-bars span:nth-child(2) {
  opacity: 0;
}

.site-header.nav-open .nav-toggle-bars span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

.nav-products {
  position: relative;
}

.nav-products-trigger {
  display: flex;
  align-items: center;
  gap: 7px;
}

.nav-chevron {
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform 180ms ease;
}

.products-menu {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  z-index: 20;
  width: min(420px, calc(100vw - 32px));
  padding: 30px 32px;
  color: #273248;
  background: #fff;
  border: 1px solid #dfe3ea;
  border-radius: 8px;
  box-shadow: 0 18px 45px rgba(31, 43, 68, 0.2);
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, -8px);
  transition: opacity 180ms ease, transform 180ms ease, visibility 180ms;
  /* Closed (and, crucially, *closing*) menu must not be hit-testable.
     `visibility` is transitioned, which means it stays `visible` for the
     whole 180ms fade-out -- so without this the menu is still catching the
     cursor while it slides 8px upward on its way out. That slide moves the
     hover target back under a cursor heading for Home/Solutions/etc, which
     re-satisfies .nav-products:hover, which reopens the menu, which slides
     it back down, which drops the hover again... a self-sustaining
     open/close oscillation (the reported flicker).
     pointer-events is deliberately NOT in the transition list above, so it
     flips to `none` on the very first frame after the pointer leaves --
     the outgoing menu is inert and cannot re-trigger itself. */
  pointer-events: none;
  isolation: isolate;
  /* will-change pre-promotes this menu to its own composited layer
     BEFORE the opacity/transform transition ever runs. Without it,
     Chrome only creates that layer at the moment the transition starts,
     and the very first painted frame of a freshly-created layer can
     reuse whatever was rasterized underneath it beforehand -- which is
     what showed up as page content ghosting through the menu's solid
     white background. Pre-promoting removes that stale-first-frame case. */
  will-change: opacity, transform;
  backface-visibility: hidden;
}

.nav-products:hover .products-menu,
.nav-products:focus-within .products-menu {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  /* Only the genuinely-open menu accepts the pointer. Sustaining the hover
     from inside the menu still works: the pointer is over a descendant of
     .nav-products, so :hover stays true and this rule keeps applying. */
  pointer-events: auto;
}

.nav-products:hover .nav-chevron,
.nav-products:focus-within .nav-chevron {
  transform: translateY(2px) rotate(225deg);
}

/* Hover bridge across the 14px gap between the trigger and the menu, so
   travelling from one to the other doesn't drop :hover mid-way.
   Sized to exactly the gap (14px, matching `top: calc(100% + 14px)` above)
   and no more. It used to be 16px tall at -16px, which overhung the nav row
   by 2px -- and because the menu carries z-index:20 while the sibling nav
   links are static, that overhang hit-tested *above* Home/Solutions/Support/
   Contact, so resting on the lower edge of any of them held the Products
   menu open and blunted that link's own hover target. */
.products-menu::before {
  content: "";
  position: absolute;
  inset: -14px 0 auto;
  height: 14px;
}

.products-menu-group {
  display: grid;
  grid-template-columns: 24px 1fr;
  gap: 14px;
}

.products-menu-group + .products-menu-group {
  margin-top: 30px;
}

.menu-category-icon {
  position: relative;
  display: block;
  width: 20px;
  height: 15px;
  margin-top: 3px;
  border: 1.5px solid #03547f;
  border-radius: 2px;
}

.menu-pc-icon::after {
  content: "";
  position: absolute;
  left: 6px;
  bottom: -5px;
  width: 7px;
  border-bottom: 1.5px solid #03547f;
}

.menu-peripheral-icon::after {
  content: "";
  position: absolute;
  left: 5px;
  right: 5px;
  bottom: 3px;
  border-bottom: 1.5px solid #03547f;
}

.site-nav .menu-category-link,
.menu-category-title {
  display: inline-block;
  padding: 0;
  color: #33405a;
  font-size: 17px;
  font-weight: 750;
  border: 0;
}

.site-nav .menu-category-link:hover {
  color: #03547f;
  border: 0;
}

.products-menu-group p {
  margin: 5px 0 14px;
  color: #6d778d;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.45;
}

.menu-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.site-nav .menu-links a {
  padding: 6px 10px;
  color: #03547f;
  background: #d9edf5;
  border: 0;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 650;
}

.site-nav .menu-links a:hover,
.site-nav .menu-links a:focus-visible {
  color: #fff;
  background: #03547f;
  border: 0;
}

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 0.86fr);
  gap: clamp(26px, 5vw, 72px);
  align-items: center;
  padding: clamp(42px, 7vw, 92px) clamp(18px, 4vw, 64px) clamp(30px, 5vw, 64px);
}

.product-hero {
  min-height: calc(100vh - 88px);
}

.hero.hero-bg {
  position: relative;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.hero-bg-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero-bg-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: right center;
}

.hero-bg-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Fades from a soft lavender-white blend (the photo's own wall tone,
     sampled from its left margin, lightened with white so it reads as a
     pale tint rather than a solid saturated lavender wash) into
     transparency, so the copy stays legible on the left without a hard
     seam where the desk setup begins. */
  background: linear-gradient(
    to right,
    #f2f0f5 0%,
    #f2f0f5 28%,
    rgba(242, 240, 245, 0.86) 42%,
    rgba(242, 240, 245, 0.3) 62%,
    rgba(242, 240, 245, 0) 80%
  );
}

.hero-bg .hero-copy {
  position: relative;
  z-index: 2;
  text-align: center;
}

.hero-bg .hero-copy .hero-actions {
  justify-content: center;
}

.hero-copy {
  max-width: 760px;
}

.eyebrow {
  margin: 0 0 12px;
  color: var(--accent-dark);
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

h1,
h2,
h3,
p {
  overflow-wrap: anywhere;
}

h1 {
  max-width: 11ch;
  margin: 0;
  font-size: clamp(3rem, 8vw, 6.5rem);
  line-height: 0.96;
  letter-spacing: 0;
}

h2 {
  margin: 0;
  font-size: clamp(2rem, 4vw, 3.5rem);
  line-height: 1.05;
  letter-spacing: 0;
}

h3 {
  margin: 0;
  font-size: 1.12rem;
  line-height: 1.25;
}

.hero-copy > p:not(.eyebrow),
.cta-band p,
.site-footer p {
  color: var(--muted);
  font-size: 1.04rem;
  line-height: 1.7;
}

.hero-copy > p:not(.eyebrow) {
  max-width: 62ch;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 28px;
}

/* Homepage hero -- scoped to #home-hero since .hero/.product-hero are the
   shared hero component reused (with different modifiers) across many
   other pages, and shouldn't be touched here. Now a 2-slide carousel: slide
   1 is the original dark "Made in India" content, slide 2 is a light
   promo banner for the digital signage standee, with prev/next arrows
   crossfading between them (hero-carousel.js). */
#home-hero {
  /* .hero (shared) sets display: grid with a 2-column copy/media template
     -- this section now has a single child (.hero-carousel) that needs
     the full width, not one grid column, so override back to a plain
     block container. */
  display: block;
  position: relative;
  overflow: hidden;
  /* .product-hero (shared) sets min-height: calc(100vh - 88px) for a
     full-viewport look on product pages -- this section's content is much
     shorter, so shrink it back down instead. */
  min-height: auto;
  padding-top: 0;
  padding-bottom: clamp(20px, 3vw, 36px);
  /* .hero (shared) also adds left/right padding -- this section should
     run edge-to-edge like the header above it, with the inset instead
     applied to each slide's own content so text doesn't touch the edge. */
  padding-left: 0;
  padding-right: 0;
}

.hero-carousel {
  position: relative;
  /* +20% on all three clamp values (was 460px / 54vw / 560px). The video
     slide fills this box, so the carousel's height is what sets it -- and
     raising it here keeps every slide the same height, which the carousel
     needs to avoid the page jumping as slides change. */
  min-height: clamp(552px, 64.8vw, 672px);
}

/* Homepage highlights band sits right below the hero -- shrink its
   shared .section top padding so the gap between the two doesn't stack
   with the hero's own bottom padding above. */
#home-highlights {
  padding-top: clamp(20px, 3vw, 36px);
  padding-bottom: clamp(20px, 3vw, 36px);
}

/* Shrink the top padding above the About Litset collage so it doesn't
   stack with #home-highlights's own bottom padding right above it. */
#about-litset {
  padding-top: clamp(20px, 3vw, 36px);
}

.hero-slide {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 420ms ease;
}

.hero-slide.is-active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
  .hero-slide {
    transition: none;
  }
}

.hero-carousel-arrow {
  position: absolute;
  top: 50%;
  z-index: 6;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: var(--ink);
  box-shadow: 0 8px 24px rgba(20, 32, 29, 0.22);
  cursor: pointer;
  transform: translateY(-50%);
  transition: background 160ms ease, transform 160ms ease;
}

.hero-carousel-arrow:hover {
  background: #fff;
  transform: translateY(-50%) scale(1.06);
}

.hero-carousel-arrow svg {
  width: 20px;
  height: 20px;
}

.hero-carousel-prev {
  left: clamp(6px, 1.4vw, 20px);
}

.hero-carousel-next {
  right: clamp(6px, 1.4vw, 20px);
}

@media (max-width: 640px) {
  .hero-carousel-arrow {
    width: 36px;
    height: 36px;
  }
}

/* -- Slide 1: original dark hero content -- */
.hero-slide-primary {
  width: 100%;
  background: #0a2436 url("assets/hero-bg-composed.jpg") center center / cover no-repeat;
}

.hero-slide-primary h1 {
  color: #fff;
}

.hero-slide-primary .hero-copy > p {
  color: rgba(255, 255, 255, 0.78);
}

.hero-slide-primary .hero-trust-badges {
  gap: 8px 14px;
  flex-wrap: nowrap;
}

.hero-slide-primary .hero-trust-badge {
  color: #fff;
  font-size: clamp(0.88rem, 1.4vw, 1.05rem);
}

.hero-slide-primary .hero-trust-badge:not(:first-child) {
  padding-left: 14px;
  border-left: 1px solid rgba(255, 255, 255, 0.25);
}

.hero-slide-primary .button.primary {
  border-color: rgba(255, 255, 255, 0.4);
}

.hero-slide-primary .button.secondary {
  color: #fff;
  background: transparent;
  border-color: rgba(255, 255, 255, 0.4);
}

/* Two-column layout: copy on the left, the live floating monitor image on
   the right. The dark gradient/glow itself still comes from the slide's
   own background-image (hero-bg-composed.jpg); this element just floats a
   real, animatable <img> on top of it. */
.home-hero-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 0.8fr);
  align-items: center;
  gap: clamp(26px, 5vw, 72px);
  width: 100%;
  padding: 0 clamp(18px, 4vw, 64px);
}

.hero-slide-primary h1 {
  max-width: 32ch;
  font-size: clamp(1.6rem, 2.8vw, 2.6rem);
  line-height: 1.15;
  white-space: nowrap;
}

/* -- Slide 2: light promo banner for the digital signage standee -- */
.hero-slide-signage {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(240px, 0.7fr);
  align-items: center;
  gap: clamp(26px, 5vw, 72px);
  padding: 0 clamp(18px, 4vw, 64px);
  background: linear-gradient(135deg, #dee2fa 0%, #eceffb 55%, #f6f5fb 100%);
}

.hero-signage-eyebrow {
  margin: 0 0 10px;
  color: var(--accent-dark);
  font-size: 0.92rem;
  font-weight: 700;
}

.hero-signage-copy h2 {
  margin: 0 0 16px;
  max-width: 12ch;
  font-size: clamp(2rem, 3.4vw, 2.9rem);
  line-height: 1.12;
  color: var(--ink);
}

.hero-signage-desc {
  max-width: 44ch;
  margin: 0 0 28px;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1.65;
}

.hero-signage-media {
  display: grid;
  place-items: center;
}

.hero-signage-media img {
  width: 100%;
  max-width: 260px;
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 24px 40px rgba(20, 32, 29, 0.18));
}

@media (max-width: 900px) {
  .hero-slide-signage {
    grid-template-columns: 1fr;
    text-align: center;
  }

  .hero-signage-media {
    order: -1;
  }
}

/* -- Slide 3: full-bleed autoplaying product video -- */
.hero-slide-video {
  width: 100%;
  height: 100%;
  background: #0a2436;
}

.hero-slide-video video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Compound selector (not just .home-hero-media-floating) so this reliably
   beats the shared .hero-media rule above regardless of source order. */
.hero-media.home-hero-media-floating {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 320px;
  overflow: visible;
  background: none;
  border-radius: 0;
  box-shadow: none;
}

.hero-media.home-hero-media-floating::before {
  content: "";
  position: absolute;
  inset: 10%;
  background: radial-gradient(ellipse at center, rgba(58, 141, 209, 0.4) 0%, rgba(58, 141, 209, 0) 70%);
  filter: blur(10px);
  z-index: 0;
}

.hero-media.home-hero-media-floating img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: auto;
  max-width: 380px;
  min-height: 0;
  object-fit: contain;
  filter: drop-shadow(0 24px 40px rgba(0, 0, 0, 0.45));
  animation: home-hero-float 5s ease-in-out infinite;
}

@keyframes home-hero-float {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-14px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-media.home-hero-media-floating img {
    animation: none;
  }
}

@media (max-width: 900px) {
  .home-hero-top {
    grid-template-columns: 1fr;
  }
}

.hero-trust-badges {
  display: flex;
  flex-wrap: nowrap;
  gap: 10px 18px;
  margin: 24px 0 4px;
}

.hero-trust-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--accent-dark);
  font-size: 0.92rem;
  font-weight: 700;
  white-space: nowrap;
}

.hero-trust-badge svg {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
}

/* Homepage hero highlights band -- a muted-blue shared strip holding 4
   clickable cards (hero-highlights.js toggles which one is .is-active on
   click, one at a time); the active card pops up dark and elevated above
   its neighbours, same "featured" treatment as the Our Process section's
   middle step. */
.hero-highlights {
  display: flex;
  align-items: stretch;
  gap: 4px;
  padding: 10px;
  background: #6b7a94;
  border-radius: 20px;
  box-shadow: var(--shadow);
}

.hero-highlight-card {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 26px 16px;
  color: #fff;
  text-align: center;
  background: transparent;
  border: none;
  border-radius: 14px;
  cursor: pointer;
  transition: transform 0.3s ease, background 0.3s ease, box-shadow 0.3s ease;
}

.hero-highlight-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  color: #fff;
}

.hero-highlight-icon svg {
  width: 24px;
  height: 24px;
}

.hero-highlight-card h3 {
  font-size: 1rem;
}

.hero-highlight-card p {
  margin: 0;
  color: rgba(255, 255, 255, 0.78);
  font-size: 0.85rem;
  line-height: 1.5;
}

.hero-highlight-card.is-active {
  background: var(--accent-dark);
  transform: translateY(-14px);
  box-shadow: 0 20px 36px rgba(3, 84, 127, 0.35);
}

@media (max-width: 780px) {
  .hero-highlights {
    flex-direction: column;
  }

  .hero-highlight-card.is-active {
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-highlight-card {
    transition: none !important;
  }
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 12px 18px;
  border: 1px solid transparent;
  border-radius: 8px;
  font-weight: 800;
}

.button.primary {
  color: #fff;
  background: var(--accent);
  box-shadow: 0 12px 24px rgba(3, 84, 127, 0.22);
}

.button.secondary {
  color: var(--accent-dark);
  background: #fff;
  border-color: var(--line);
}

.hero-media {
  overflow: hidden;
  min-height: 430px;
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.hero-media img {
  width: 100%;
  height: 100%;
  min-height: 430px;
  object-fit: cover;
}

.section {
  padding: clamp(52px, 8vw, 104px) clamp(18px, 4vw, 64px);
}

.category-hero {
  padding: clamp(28px, 5vw, 58px) clamp(18px, 4vw, 64px) clamp(40px, 7vw, 84px);
}

/* Solutions "Learn More" detail pages -- shared hero used by all seven
   card sub-pages (enterprise computing, smart classrooms, digital
   signage, etc). Full-bleed photo (reusing that card's own tile image)
   with a left-to-right fade so the copy stays legible on the left,
   shorter than a full-viewport product-hero since these are secondary
   pages, not landing pages. */
.solution-detail-hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: clamp(420px, 56vh, 560px);
  padding: clamp(44px, 8vw, 90px) clamp(18px, 5vw, 72px);
  overflow: hidden;
}

.solution-detail-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.solution-detail-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.solution-detail-hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(90deg, #f2f0f5 0%, rgba(242, 240, 245, 0.92) 32%, rgba(242, 240, 245, 0.5) 52%, rgba(242, 240, 245, 0) 70%);
}

.solution-detail-hero-content {
  position: relative;
  z-index: 2;
  max-width: 620px;
}

.solution-detail-hero-content h1 {
  max-width: none;
  color: var(--ink);
  font-size: clamp(2.1rem, 4.2vw, 2.9rem);
}

.solution-detail-hero-content > p:not(.eyebrow) {
  max-width: 58ch;
  margin-top: 14px;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1.65;
}

.solution-detail-hero-content .hero-actions {
  margin-top: 26px;
}

@media (max-width: 720px) {
  .solution-detail-hero-overlay {
    background: rgba(242, 240, 245, 0.9);
  }
}

/* Contact page -- "Our Location" map section, below the request-a-quote
   card. */
.contact-map-section {
  max-width: 1800px;
  margin: 0 auto;
  text-align: center;
}

.contact-map-heading {
  margin: 0 auto 32px;
}

.contact-map-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 18px;
  padding: 7px 18px;
  color: var(--accent-dark);
  background: rgba(3, 84, 127, 0.08);
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 800;
}

.contact-map-heading h2 {
  max-width: 900px;
  margin: 0 auto;
}

/* Homepage "Prefer a Real Map?" section -- an A/B alternative to the
   cinematic presence.js section above it, using a real Leaflet +
   OpenStreetMap map instead of a hand-plotted satellite photo. Same
   bordered/rounded card treatment as .contact-map-embed. */
.presence-map-wrap {
  position: relative;
  max-width: 1800px;
  margin: 0 auto;
  /* The "Scroll to Explore" link jumps to this element's native anchor
     position -- without this, the sticky 88px header covers that same
     amount of the map after scrolling. */
  scroll-margin-top: 108px;
}

.presence-map-embed {
  height: clamp(420px, 55vw, 620px);
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
}

.presence-map-embed .leaflet-container {
  width: 100%;
  height: 100%;
  font-family: inherit;
}

.presence-map-pin-diamond {
  display: block;
  width: 22px;
  height: 22px;
  background: #ffb545;
  border: 3px solid #fff;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(20, 32, 29, 0.35);
  transform: rotate(45deg);
}

.presence-map-popup-city {
  margin: 0 0 4px;
  color: var(--ink);
  font-weight: 800;
}

.presence-map-popup-products {
  margin: 0 0 8px;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

.presence-map-popup-status {
  display: inline-block;
  margin: 0;
  padding: 4px 10px;
  color: #7a4a06;
  background: #ffe6b8;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 800;
}

.contact-map-embed {
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
}

.contact-map-embed iframe {
  display: block;
  width: 100%;
  height: 420px;
}

@media (max-width: 720px) {
  .contact-map-embed iframe {
    height: 320px;
  }
}

/* "Prefer to Browse First?" CTA -- centered/stacked instead of the
   shared .cta-band class's left-text/right-button row, scoped to this
   section only (same treatment as #desktop-cta and .monitor-cta). */
#contact-browse-cta {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

#contact-browse-cta > div {
  display: flex;
  flex-direction: column;
  align-items: center;
}

#contact-browse-cta h2 {
  max-width: 1450px;
  margin: 0 auto;
}

@media (max-width: 720px) {
  #contact-browse-cta {
    align-items: center;
  }
}

/* Become a Dealer page hero -- a single self-contained promo banner
   image (its own "Become a Dealer" heading, tagline, and stat icons are
   already baked into the graphic), so this section is just an edge-to-
   edge image with no separate HTML heading/copy overlaid on top. */
#dealer-hero {
  overflow: hidden;
}

#dealer-hero img {
  display: block;
  width: 100%;
  /* The banner's own 1672x941 proportions, so nothing is cropped at any
     width -- the full frame shows, headline through to the pen on the
     desk. No max-height and no object-fit crop: the section simply is the
     image. `contain` rather than `cover` so that if a future replacement
     graphic has a different ratio it letterboxes instead of silently
     cutting the artwork; with a matching image the two behave identically.

     Note this makes the hero as tall as 1080px on a 1920px screen -- the
     whole viewport on a 1080p display. That's the trade for showing the
     banner uncropped, since the artwork is a fixed 1.78:1 composition. */
  aspect-ratio: 1672 / 941;
  object-fit: contain;
  object-position: top;
}

/* Careers page hero -- a single self-contained promo banner image (its
   own "Build Your Future With Us" heading, tagline, and value-prop icons
   are already baked into the graphic), same treatment as #dealer-hero. */
#careers-hero {
  overflow: hidden;
}

#careers-hero img {
  display: block;
  width: 100%;
  /* Same crop treatment as #dealer-hero -- trims empty desk space off
     the bottom while keeping the heading/tagline/icons fully visible. */
  aspect-ratio: 1672 / 643;
  object-fit: cover;
  object-position: top;
}

/* Contact page hero only -- bread photo as a full-bleed background
   (its own empty backdrop up top, loaves peeking in along the bottom
   edge) with a centered heading/line over it, instead of the shared
   left-aligned .category-hero text block used on other pages. */
#contact-hero {
  position: relative;
  overflow: hidden;
  /* Tall enough that cropping the photo to this band (object-position:
     top) still reaches down into the loaves instead of only showing
     the empty backdrop at the top of the source photo. */
  min-height: clamp(440px, 32vw, 620px);
  padding-top: clamp(48px, 8vw, 84px);
  padding-bottom: clamp(48px, 8vw, 84px);
}

#contact-hero .contact-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

/* The source photo (contact-page-bg-bread.webp) contains the same row of
   loaves twice, one above the other, separated by a thin seam -- that
   duplication is baked into the file, not caused by any CSS. It never
   showed on a wide screen because `cover` cropped everything below ~70% of
   the photo away, but as the hero got relatively taller on a phone more of
   the file came into view and the second row appeared.

   The image is now contact-page-bread-band.webp: the first row of loaves
   only, cropped out of the original (source rows 440-794 of 1228), 2200x354
   and 6.21:1.

   It's placed as a band across the bottom of the hero rather than filling
   it. Above the band is the section's own background, which is the exact
   colour the photo's backdrop already was, so there's no visible seam --
   and that's where the copy sits. `object-position: top` keeps the tops of
   the loaves and trims their bases when the band is shorter than the
   image's ratio, which is how the original desktop crop looked. */
#contact-hero .contact-hero-media {
  top: auto;
  height: clamp(96px, 16vw, 190px);
}

#contact-hero .contact-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}

/* Reserve exactly the band's height plus the gap, so the copy always clears
   the loaves by the same 24px no matter how tall either one gets. */
#contact-hero {
  padding-bottom: calc(clamp(96px, 16vw, 190px) + 24px);
}

/* On a phone the 440px floor left the hero much taller than its contents
   needed, and all of that slack landed between the copy and the band.
   Dropping the floor lets the section hug the copy, so the only space left
   is the 24px above. */
@media (max-width: 800px) {
  #contact-hero {
    min-height: 0;
  }
}

#contact-hero .breadcrumb,
#contact-hero .hero-copy {
  position: relative;
  z-index: 1;
}

#contact-hero .breadcrumb {
  max-width: none;
  margin-left: 0;
}

#contact-hero .hero-copy {
  max-width: 720px;
  margin: 40px auto 0;
  text-align: center;
}

#contact-hero .hero-copy h1 {
  max-width: none;
  font-size: clamp(3.6rem, 8vw, 6.2rem);
}

#contact-hero .hero-copy > p:not(.eyebrow) {
  max-width: 52ch;
  margin: 18px auto 0;
  font-size: 1.3rem;
}

/* Support page hero only -- team photo as a full-bleed background
   (empty backdrop on its own left side, subjects on the right) with a
   left-aligned heading/copy/buttons over it, instead of the shared
   .category-hero's plain text-only block. */
#support-hero,
#warranty-hero {
  position: relative;
  overflow: hidden;
  /* Sized to the photo's own 2752x1536 proportions (instead of a fixed
     min-height) so the full image always shows uncropped -- the section
     gets shorter/taller with viewport width rather than zooming or
     cutting into the photo. */
  aspect-ratio: 2752 / 1536;
  display: flex;
  flex-direction: column;
}

#support-hero .hero-copy,
#warranty-hero .hero-copy {
  /* Auto top/bottom margins on a column-flex child center it in
     whatever vertical space is left after the breadcrumb above it,
     without moving the breadcrumb itself. */
  margin-top: auto;
  margin-bottom: auto;
}

#support-hero .support-hero-media,
#warranty-hero .support-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

#support-hero .support-hero-media img,
#warranty-hero .support-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
}

#support-hero .support-hero-overlay,
#warranty-hero .support-hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Fades from the photo's own light backdrop tone (sampled from its
     left margin) into transparency, so text stays legible on the left
     without a hard seam where the photo's content begins. */
  background: linear-gradient(90deg, #cfcdda 0%, rgba(207, 205, 218, 0.85) 32%, rgba(207, 205, 218, 0) 62%);
}

#support-hero .breadcrumb,
#warranty-hero .breadcrumb,
#support-hero .hero-copy,
#warranty-hero .hero-copy {
  position: relative;
  z-index: 2;
}

#support-hero .breadcrumb,
#warranty-hero .breadcrumb {
  max-width: none;
  margin-left: 0;
}

#support-hero .hero-copy,
#warranty-hero .hero-copy {
  max-width: 46ch;
}

#support-hero .hero-copy h1,
#warranty-hero .hero-copy h1 {
  /* Much smaller than the shared h1 default (which was tall enough,
     combined with the aspect-ratio-constrained section height above,
     to push the paragraph below it past the section's overflow:hidden
     edge and out of view). Wraps to about 2-3 lines instead of 4+. */
  max-width: 22ch;
  font-size: clamp(1.7rem, 3vw, 2.5rem);
  line-height: 1.15;
}

/* Center the copy within its own left-hand column -- same treatment as the
   panel and signage heroes. The column itself doesn't move: it stays at the
   left of the frame (46ch, well clear of the photo's subjects), only the
   text inside it is centered.

   The h1 needs explicit auto margins on top of `text-align`: its 22ch cap
   is narrower than the 46ch column, and `h1 { margin: 0 }` would otherwise
   leave that narrower block sitting hard left with only its text centered
   inside it. */
#support-hero .hero-copy,
#warranty-hero .hero-copy {
  text-align: center;
}

#support-hero .hero-copy h1,
#warranty-hero .hero-copy h1 {
  margin-left: auto;
  margin-right: auto;
}

#support-hero .hero-copy > p:not(.eyebrow),
#warranty-hero .hero-copy > p:not(.eyebrow) {
  margin-left: auto;
  margin-right: auto;
}

#support-hero .hero-actions,
#warranty-hero .hero-actions {
  justify-content: center;
}

@media (max-width: 720px) {
  /* The full uncropped-image aspect ratio gets too short on narrow
     screens to also fit the heading/copy/buttons -- fall back to a
     fixed minimum height (with light cropping) here only, rather than
     letting text overflow or clip. */
  #support-hero,
#warranty-hero {
    aspect-ratio: auto;
    min-height: 360px;
  }

  #support-hero .support-hero-media img,
#warranty-hero .support-hero-media img {
    object-fit: cover;
    object-position: right center;
  }

  #support-hero .support-hero-overlay,
#warranty-hero .support-hero-overlay {
    /* A flat wash instead of the desktop left-to-right gradient --
       on a narrow/tall crop there's no guaranteed empty side for text
       to sit over, so the whole photo gets evenly dimmed instead. */
    background: rgba(207, 205, 218, 0.82);
  }
}

/* ===========================================================================
   Warranty hero -- the product-range render
   ---------------------------------------------------------------------------
   Everything above is shared with #support-hero, which was tuned for a
   different photo. Three things differ here:

   The image is 1672x941 rather than 2752x1536, so it gets its own ratio --
   `cover` then has nothing to crop, and the section stays exactly as tall as
   the artwork at any width.

   The products sit in the right-hand 59% of the frame: measured, the glow
   ring and the wall-mounted panel begin at 40.6% across. The shared overlay
   fades out at 62%, which would have washed over the panel and the standee.
   This one is clear by 38%, just before they start, and is tinted #d3cce6 --
   the average colour of the render's own empty left-hand side -- so the veil
   is invisible where it's solid.

   The copy column is capped in percentage as well as characters. 46ch alone
   is fine on a wide screen but works out at ~47% of a 900px window, which
   would put the text over the monitor.
   ========================================================================= */
#warranty-hero {
  aspect-ratio: 1672 / 941;
}

#warranty-hero .support-hero-media img {
  object-fit: cover;
  object-position: right center;
}

#warranty-hero .support-hero-overlay {
  background: linear-gradient(
    90deg,
    #d3cce6 0%,
    rgba(211, 204, 230, 0.92) 20%,
    rgba(211, 204, 230, 0.55) 30%,
    rgba(211, 204, 230, 0) 38%
  );
}

#warranty-hero .hero-copy {
  max-width: min(46ch, 36%);
}

/* ---------------------------------------------------------------------------
   The intro paragraph is dropped as soon as the two buttons stop fitting on
   one line.

   That happens at about 1160px. The copy column is capped at 36% of the
   hero, and the buttons need roughly 420px side by side -- below that width
   the column is narrower than they are, so "Get Support" wraps onto a second
   row. The hero's height is tied to the render's aspect ratio rather than to
   its contents, so the extra row has nowhere to go and the button is cut off
   by `overflow: hidden`.

   Losing the paragraph frees about 140px, which is more than the wrapped row
   costs, so everything fits again down to the 720px switch. The line only
   restates what the heading and the two buttons already say.

   `display: none` also hides it from screen readers -- the right call for a
   line that repeats the heading's point, but not a purely visual change.
   ------------------------------------------------------------------------ */
@media (max-width: 1160px) {
  #warranty-hero .hero-copy > p:not(.eyebrow) {
    display: none;
  }
}

@media (max-width: 720px) {
  /* Crop into the render rather than showing all of it. The left 40% of the
     frame is empty wall -- fine on a wide screen where the copy sits in it,
     but on a phone the copy goes full width and that empty area is just
     dead space with the products squeezed into a shrinking right-hand strip.
     A taller box makes `cover` scale up, and `object-position: right` means
     the whole of the overflow is taken off the left, so the products fill
     the frame.
     75vw gives a consistent 25% trim from 480px upwards, and more below
     that where the 360px floor takes over.

     Height, not `aspect-ratio`: a ratio is a fixed size, so a long headline
     or a larger default font would overflow it and be cut off by the hero's
     `overflow: hidden`. A min-height is a floor -- the box grows with the
     copy instead. The explicit `aspect-ratio: auto` matters because the
     ratio set for wide screens is declared later in this file than the
     shared rule that releases it here, so it would otherwise still apply. */
  #warranty-hero {
    aspect-ratio: auto;
    min-height: max(360px, 75vw);
  }

  /* Below this the copy takes the full width over an even wash (see the
     shared rule above), so the percentage cap would only squeeze it.

     The auto side margins are the part that matters. `.hero-copy` is a block
     with a max-width and no horizontal margins, so it sits against the left
     padding -- correct while it's a column beside the products, but once the
     image is blurred behind it and the layout is a single centred stack, it
     left the text noticeably off-centre while the eyebrow, heading and
     buttons were each centred *within* that off-centre block. Auto margins
     centre the block itself, so it lines up with the middle of the hero. */
  #warranty-hero .hero-copy {
    max-width: 46ch;
    margin-left: auto;
    margin-right: auto;
  }


  /* The copy stays, and the photo is blurred behind it instead.
     `filter` on the image rather than `backdrop-filter` on the overlay:
     backdrop-filter has to composite the whole hero every frame and is
     expensive on the phones this affects, while blurring the image is done
     once.

     The scale is what makes it work. A blur samples pixels from outside the
     element, so at the edges it has nothing to sample and fades into
     transparency -- you get a soft, washed-out border around the photo.
     Scaling up pushes those edges outside the hero's `overflow: hidden`
     boundary, so only clean, fully-blurred pixels are visible.

     The binding constraint is the top and bottom edges, not the sides: the
     image is already cropped 25-44% horizontally by `cover`, so it overflows
     the box by hundreds of pixels left and right, but vertically it fits
     exactly. A 4px radius bleeds roughly 12px, and the shortest the box gets
     is the 360px floor -- so it needs at least 1 + 24/360 = 1.067. 8% clears
     that at every size.

     The wash comes down from 0.82 to 0.5 to compensate: with the detail
     already softened, it takes far less veil to keep the text readable, and
     the products stay recognisable behind it instead of being flattened
     into a lavender field. */
  #warranty-hero .support-hero-media img {
    filter: blur(4px);
    transform: scale(1.08);
  }

  #warranty-hero .support-hero-overlay {
    background: rgba(211, 204, 230, 0.5);
  }
}

/* Support page -- "Warranty Check" heading. The shared .section-heading is
   a wide flex row (eyebrow far left, heading far right) built for sections
   that have a full-width grid/row underneath -- this section only has a
   single centered card below it, so that split layout leaves both lines
   stranded in opposite corners with a huge empty middle. Override to a
   normal stacked, centered heading instead. */
#warranty-check .section-heading {
  display: block;
  max-width: 720px;
  margin: 0 auto 32px;
  text-align: center;
}

/* Text sized up ~30% from the shared eyebrow/h3 defaults (0.78rem/1.12rem)
   for this section only. */
#warranty-check .section-heading h3 {
  max-width: none;
  font-size: 1.75rem;
}

#warranty-check .section-heading .eyebrow {
  font-size: 1.2rem;
}

/* Support page -- "Warranty Check" card. Starts centered in the section;
   once a lookup succeeds, it slides to the left edge and the result panel
   (photo + details) fades in beside it. The centering trick (left:50% +
   translateX(-50%)) is deliberate: both `left` and `transform` are real
   animatable values, so the shift-to-left transition runs smoothly with
   plain CSS -- no JS position math needed. */
/* ---------------------------------------------------------------------------
   Warranty lookup: form, and the result beside or below it.

   Both children used to be `position: absolute` inside a fixed-height stage,
   which caused two separate bugs:

     - Absolutely positioned children contribute no height, so the stage
       could only ever be as tall as its min-height. A result taller than
       that spilled out and overlapped the section underneath.
     - The result was pinned with `left: calc(min(720px,100%) + 52px);
       right: 0`. Once the viewport was narrower than the form plus that
       gap, the remaining width collapsed and the result was squeezed into
       a sliver against the right edge.

   A grid fixes both: the stage is as tall as whatever is in it, and the
   result drops below the form instead of being crushed when there isn't
   room for two columns.
   ------------------------------------------------------------------------ */
.warranty-check-stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  align-items: start;
  gap: 28px;
}

/* Side by side only where both fit properly: the form is up to 720px and the
   result needs ~360px before its label/value rows start wrapping badly. */
@media (min-width: 1120px) {
  .warranty-check-stage.has-result {
    grid-template-columns: minmax(0, 720px) minmax(360px, 1fr);
    justify-items: stretch;
  }
}

.warranty-check-card {
  width: min(720px, 100%);
  background: var(--panel);
  border-radius: 22px;
  box-shadow: var(--shadow);
  padding: clamp(20px, 5vw, 44px);
  text-align: center;
}

/* Everything in this card used to be sized in fixed rem -- a 1.9rem
   heading, 1.5rem input and button, on top of a flat 44px padding. None of
   it scaled down, so on a narrow screen the card's content box shrank while
   its contents didn't: "Check Warranty" at 1.5rem bold needs ~240px
   including the button's own padding, which is more than the whole card had
   left, and the text spilled out of both sides. The left half of that spill
   ran off the edge of the page, which is what was getting cut off.

   Clamped so the card's contents track its width; the upper bounds are the
   original desktop values, so nothing changes on a large screen. */
.warranty-check-card h4 {
  margin: 0 0 clamp(16px, 3vw, 26px);
  font-size: clamp(1.25rem, 4.4vw, 1.9rem);
}

.warranty-check-card .form-field {
  text-align: left;
  margin-top: 0;
}

.warranty-check-card .form-field label {
  font-size: clamp(1rem, 3vw, 1.4rem);
}

.warranty-check-card .form-field input {
  padding: clamp(11px, 2vw, 16px) clamp(13px, 2.5vw, 20px);
  font-size: clamp(1rem, 3.2vw, 1.5rem);
}

.warranty-check-card button.button.primary {
  width: 100%;
  margin-top: clamp(16px, 3vw, 24px);
  min-height: clamp(50px, 9vw, 70px);
  padding: clamp(12px, 2.2vw, 18px) clamp(14px, 3vw, 26px);
  font-size: clamp(1rem, 3.2vw, 1.5rem);
}

.warranty-check-card .form-status {
  text-align: left;
  font-size: clamp(0.9rem, 2.6vw, 1.35rem);
}

/* (The card used to slide left here. With the grid above it simply occupies
   the first column, so there's nothing to move.) */

.warranty-check-result {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 34px;
  align-items: flex-start;
  background: var(--panel);
  border-radius: 22px;
  box-shadow: var(--shadow);
  padding: 36px 44px;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.warranty-check-stage.has-result .warranty-check-result {
  opacity: 1;
  transform: none;
}

.warranty-check-photo img {
  width: 230px;
  height: 230px;
  object-fit: cover;
  border-radius: 16px;
  flex-shrink: 0;
}

.warranty-check-details {
  flex: 1 1 320px;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 15px 24px;
  margin: 0;
}

.warranty-check-details dt {
  color: var(--muted);
  font-weight: 700;
  font-size: 1.4rem;
}

.warranty-check-details dd {
  margin: 0;
  color: var(--ink);
  font-weight: 650;
  font-size: 1.4rem;
}

.warranty-check-details dd.status-active { color: #1a8f5e; }
.warranty-check-details dd.status-expiring_soon { color: #b9830a; }
.warranty-check-details dd.status-expired { color: #c23b3b; }

@media (max-width: 720px) {
  /* These used to undo the absolute positioning that the stage no longer
     uses. All that's left is the phone layout for the result itself: the
     photo and the detail list stack instead of sitting side by side. */
  .warranty-check-result {
    flex-direction: column;
    gap: 20px;
    padding: 24px 20px;
  }
}

/* Support page -- "Raise a Ticket" heading. Same override as
   #warranty-check above and for the same reason: a single centered card
   sits below it, so the shared wide-row .section-heading would leave both
   lines stranded in opposite corners. */
#raise-ticket .section-heading {
  display: block;
  max-width: 720px;
  margin: 0 auto 32px;
  text-align: center;
}

#raise-ticket .section-heading h3 {
  max-width: none;
  font-size: 1.75rem;
}

#raise-ticket .section-heading .eyebrow {
  font-size: 1.2rem;
}

/* Support page -- "Raise a Ticket" form. A single card (unlike the
   Warranty Check's slide-to-the-side layout) since there's no second panel
   of results to reveal -- successful submission just swaps the form for a
   confirmation message in the same spot. */
.ticket-form-stage {
  max-width: 760px;
  margin: 0 auto;
}

.ticket-form-card,
.ticket-success {
  background: var(--panel);
  border-radius: 22px;
  box-shadow: var(--shadow);
  padding: clamp(28px, 4vw, 44px);
}

.ticket-form-card .form-row:first-child,
.ticket-form-card > .form-field:first-child {
  margin-top: 0;
}

.ticket-form-card button.button.primary {
  width: 100%;
  margin-top: 8px;
}

.ticket-success {
  text-align: center;
}

.ticket-success-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  margin-bottom: 16px;
  border-radius: 50%;
  color: #fff;
  background: #1a8f5e;
}

.ticket-success-icon svg {
  width: 28px;
  height: 28px;
}

.ticket-success h4 {
  margin: 0 0 10px;
  font-size: 1.6rem;
}

.ticket-success p {
  max-width: 46ch;
  margin: 0 auto 22px;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1.6;
}

.ticket-success #ticket-success-ref {
  color: var(--ink);
}

@media (max-width: 720px) {
  .ticket-form-card,
  .ticket-success {
    border-radius: 16px;
  }
}

/* Desktop PC page hero -- a solid dark section (using the cabinet photo's
   own near-black studio tone as the background color) with the full,
   uncropped product photo on the left and the heading/copy on the right,
   instead of a boxed image beside light-background text. */
.desktop-hero {
  position: relative;
  display: grid;
  align-items: center;
  justify-items: end;
  /* Takes the photo's own 2200x1228 proportions so `cover` crops nothing --
     the tower stays put in the left ~42% and the copy keeps the clear dark
     space on the right. A fixed viewport height cropped the sides as the
     window narrowed, pushing the tower toward the text. */
  aspect-ratio: 2200 / 1228;
  min-height: 0;
  padding: clamp(44px, 8vw, 110px) clamp(18px, 5vw, 72px);
  overflow: hidden;
  /* Fallback behind the photo (matches its own dark backdrop) in case the
     image is still loading or doesn't quite reach an extreme edge. */
  background: #131419;
}

.desktop-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.desktop-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Anchored left so the cabinet itself (which sits toward the left of
     the source photo) stays fully in frame as the section crops to fill
     every width; the empty dark backdrop on the right crops away first. */
  object-position: left center;
}

.desktop-hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Dark scrim on the right for text legibility, fading out before it
     reaches the cabinet on the left. */
  background: linear-gradient(270deg, rgba(8, 9, 12, 0.82) 0%, rgba(8, 9, 12, 0.52) 40%, rgba(8, 9, 12, 0) 68%);
}

.desktop-hero-content {
  position: relative;
  z-index: 2;
  max-width: clamp(520px, 48vw, 940px);
  text-align: center;
}

.desktop-hero-content h2 {
  max-width: none;
  margin: 0 auto;
  color: #fff;
  font-size: clamp(2.6rem, 5.4vw, 4.4rem);
}

.desktop-hero-content p {
  max-width: 48ch;
  margin: 16px auto 0;
  color: rgba(255, 255, 255, 0.78);
  font-size: 1.05rem;
  line-height: 1.7;
}

.desktop-hero-content .hero-actions {
  margin-top: 28px;
  justify-content: center;
}

@media (max-width: 980px) {
  .desktop-hero {
    min-height: auto;
    padding-top: 46vh;
    justify-items: start;
    align-items: end;
  }

  .desktop-hero-overlay {
    background: linear-gradient(180deg, rgba(8, 9, 12, 0) 0%, rgba(8, 9, 12, 0.55) 45%, rgba(8, 9, 12, 0.92) 100%);
  }

  .desktop-hero-content {
    max-width: none;
  }
}

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  max-width: 1160px;
  margin: 0 auto 22px;
  color: var(--muted);
  font-size: 0.92rem;
  font-weight: 700;
}

.breadcrumb a {
  color: var(--accent-dark);
}

.category-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(320px, 1fr);
  gap: clamp(24px, 5vw, 68px);
  align-items: center;
  max-width: 1800px;
  margin: 0 auto;
  /* Clips the scroll-zoom image's zoomed-in (scale > 1) state to its own
     box -- see scroll-zoom.js. Doesn't affect layout/spacing. */
  overflow: hidden;
}

.category-layout h1 {
  max-width: 12ch;
  font-size: clamp(2.9rem, 6.6vw, 5.6rem);
}

.category-layout p:not(.eyebrow) {
  max-width: 62ch;
  color: var(--muted);
  font-size: 1.04rem;
  line-height: 1.7;
}

/* /product/configure/ only. That page's hero description is empty in the
   markup and filled once /api/product-lines/ answers, so without a floor the
   "Start Configuring" button sits high and then gets shoved down when the
   text lands. Three lines at the line-height above (1.7 x 1.04rem) is what
   the panel and signage descriptions actually occupy in the narrow centred
   column, so reserving that much absorbs the fill with no visible movement.
   A floor, not a fixed height -- a longer description still grows the block
   rather than being clipped. */
.hero-copy-reserve {
  min-height: calc(1.7 * 1.04rem * 3);
}

.category-layout img {
  width: 100%;
  min-height: 420px;
  object-fit: cover;
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.section-heading {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 24px;
  max-width: 1800px;
  margin: 0 auto 28px;
}

.section-heading h2 {
  max-width: 780px;
}

/* Homepage "Solutions" heading -- centered/stacked instead of the
   shared class's left-eyebrow/right-heading row, scoped to this section
   only (the shared .section-heading class is reused as that row on many
   other pages and sections). */
#from-solutions .section-heading {
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  margin: 0 auto 36px;
}

#from-solutions .from-blog-subtitle {
  max-width: 640px;
  margin: 0 auto;
  color: var(--muted);
  font-size: 1.15rem;
  line-height: 1.6;
}

.product-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  max-width: 1800px;
  margin: 0 auto;
}

.product-grid.three-up {
  align-items: stretch;
}

.product-card {
  overflow: hidden;
  display: grid;
  min-height: 420px;
  /* Shrinks the card slightly within its grid cell (on top of the grid's
     own 18px gap) so the scroll-zoom-card scale-up (see scroll-zoom.js,
     1.06x) has room to grow into without visually touching the next card
     -- the 18px gap alone was almost entirely eaten up by that zoom. */
  margin: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 12px 36px rgba(20, 32, 29, 0.06);
  transition: transform 180ms ease, box-shadow 180ms ease;
}

.product-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow);
}

.product-card img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
}

.product-card div {
  display: grid;
  align-content: start;
  gap: 12px;
  padding: 20px;
}

.product-card p,
.feature-list p {
  margin: 0;
  color: var(--muted);
  line-height: 1.62;
}

.product-card span {
  margin-top: 8px;
  color: var(--accent-dark);
  font-weight: 800;
}

.model-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  max-width: 1800px;
  margin: 0 auto;
}

/* Desktop Options section only -- widened well past the shared 1160px cap
   so each workspace photo renders larger/closer to its native resolution,
   but still capped so cards don't balloon to an unreasonable size on
   ultra-wide monitors. */
#desktop-options .model-grid {
  max-width: 1800px;
}

/* Match the heading row to the same widened cap so the eyebrow lines up
   with the start of card 1 and the heading lines up with the end of
   card 3, instead of sitting centered and inboard of the wider grid. */
#desktop-options .section-heading {
  max-width: 1800px;
}

#desktop-options .section-heading h3,
#pricing .section-heading h3,
.comparison-section .section-heading h2 {
  font-size: 1.35rem;
}

#desktop-options .section-heading .eyebrow,
#pricing .section-heading .eyebrow,
.comparison-section .section-heading .eyebrow {
  font-size: 0.92rem;
}

/* Match the pricing row's widened cap (see .desktop-model-row below) so
   the heading's edges line up with the row instead of sitting narrower
   and inboard of it. */
#pricing .section-heading {
  max-width: 1800px;
}

.model-card {
  overflow: hidden;
  display: grid;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 12px 36px rgba(20, 32, 29, 0.06);
}

.model-card img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
}

.model-card div {
  padding: 20px;
}

.model-card p:not(.eyebrow) {
  color: var(--muted);
  line-height: 1.62;
}

.model-card ul {
  display: grid;
  gap: 8px;
  margin: 16px 0 0;
  padding-left: 20px;
  color: var(--ink);
  line-height: 1.5;
}

.pricing-section {
  background: #ffffff;
  border-top: 1px solid var(--line);
}

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  max-width: 1800px;
  margin: 0 auto;
}

.price-card {
  position: relative;
  display: grid;
  gap: 20px;
  align-content: space-between;
  min-height: 520px;
  padding: 24px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
}

.price-card.featured {
  background: #03547f;
  color: #ffffff;
  border-color: #03547f;
  box-shadow: var(--shadow);
}

.price-card.featured p,
.price-card.featured li,
.price-card.featured .eyebrow {
  color: rgba(255, 255, 255, 0.78);
}

.price-badge {
  position: absolute;
  top: 18px;
  right: 18px;
  padding: 6px 10px;
  color: #03547f;
  background: var(--gold);
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 900;
}

.price-top p:not(.eyebrow) {
  color: var(--muted);
  line-height: 1.62;
}

.price {
  margin: 12px 0;
  color: var(--accent-dark);
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 900;
  line-height: 1;
}

.price-card ul {
  display: grid;
  gap: 10px;
  margin: 0;
  padding-left: 20px;
  line-height: 1.5;
}

.pricing-note {
  max-width: 1800px;
  margin: 18px auto 0;
  color: var(--muted);
  line-height: 1.6;
}

/* Line up with the widened pricing row/heading above (see
   .desktop-model-row and #pricing .section-heading) instead of sitting
   narrower and indented relative to card 1. */
#pricing .pricing-note {
  max-width: 1800px;
}

/* Line up with the widened compare table below. */
.comparison-section .section-heading {
  max-width: 1800px;
}

/* Desktop Strengths -- restructured from the shared .spec-band's
   left-label/right-content split into the same heading-row-above-a-
   full-width-row pattern used by the other sections on this page
   (Desktop Options, Desktop Pricing, Compare), with all 4 cards in a
   single row instead of a 2x2 grid. Scoped to this section's id so the
   shared .spec-band/.spec-grid classes (also used on product/pc/index.html)
   are untouched. */
#desktop-strengths {
  display: block;
}

#desktop-strengths .section-heading {
  max-width: 1800px;
}

#desktop-strengths .section-heading h2 {
  font-size: 1.35rem;
}

/* ===========================================================================
   Long-form legal copy -- warranty policy, terms & conditions
   ---------------------------------------------------------------------------
   A readable measure and generous line height for text that's read rather
   than scanned, plus sensible defaults for the headings, lists and tables a
   policy tends to contain, so the content can be written as plain HTML
   without needing a class on every element.
   ========================================================================= */
.legal-copy {
  max-width: 78ch;
  margin: 0 auto;
  color: #3d4b5d;
  font-size: 1.02rem;
  line-height: 1.75;
}

.legal-copy h3 {
  margin: 34px 0 10px;
  color: var(--ink);
  font-size: 1.25rem;
  line-height: 1.3;
}

.legal-copy h4 {
  margin: 24px 0 8px;
  color: var(--ink);
  font-size: 1.05rem;
}

.legal-copy > :first-child {
  margin-top: 0;
}

.legal-copy p {
  margin: 0 0 16px;
}

.legal-copy ul,
.legal-copy ol {
  margin: 0 0 18px;
  padding-left: 22px;
}

.legal-copy li {
  margin-bottom: 8px;
}

.legal-copy strong {
  color: var(--ink);
}

.legal-copy table {
  width: 100%;
  margin: 8px 0 22px;
  border-collapse: collapse;
  font-size: 0.95rem;
}

.legal-copy th,
.legal-copy td {
  padding: 10px 14px;
  border: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

.legal-copy th {
  background: var(--sky);
  color: var(--ink);
  font-weight: 700;
}

/* ===========================================================================
   Warranty page -- headings and section rhythm
   ---------------------------------------------------------------------------
   The shared .section-heading is a row with the eyebrow on the left and the
   heading pushed to the far right, which works above a wide grid but on a
   1900px screen left them at opposite ends of the page with nothing between.
   Stacked and centered here, and sized up: these are the only landmarks in a
   long document, so they need to read as headings rather than labels.

   The section padding comes down too. At clamp(52px, 8vw, 104px) top and
   bottom, consecutive sections put over 200px of empty space between one
   block of text and the next.
   ========================================================================= */
.warranty-page .section-heading {
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}

.warranty-page .section-heading h2,
.warranty-page .section-heading h3 {
  max-width: none;
  margin: 0;
  font-size: clamp(1.65rem, 2.7vw, 2.5rem);
  line-height: 1.2;
}

.warranty-page .section-heading .eyebrow {
  margin-bottom: 0;
  font-size: clamp(0.88rem, 1.1vw, 1.05rem);
}

.warranty-page .section {
  padding-top: clamp(30px, 3.4vw, 52px);
  padding-bottom: clamp(30px, 3.4vw, 52px);
}

/* The serial-lookup form and its result are both absolutely positioned, so
   the stage needs a reserved height or it would collapse to nothing and the
   next section would run underneath. 540px was more than the form actually
   needs, and the surplus showed up as blank space below the card. */
.warranty-page .warranty-check-stage {
  min-height: 470px;
}

/* ===========================================================================
   Warranty policy -- one card per block, stacked
   ---------------------------------------------------------------------------
   Covered and Not-covered were side by side, but the exclusions run about
   twice as long as the coverage list (524 words against 255) -- that's
   inherent, since "manufacturing defects under normal use" covers a lot in
   one line while exclusions have to be specific. Two columns of such
   different lengths left a tall card next to a short one with a column of
   dead space beside it.

   Stacked instead, one card after another, all four policy blocks sharing
   the same treatment so the page reads as a sequence of document cards.
   ========================================================================= */
.coverage-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(18px, 2.2vw, 28px);
}

.coverage-col,
.policy-card {
  max-width: min(860px, 100%);
  margin-inline: auto;
  padding: clamp(22px, 2.6vw, 40px) clamp(20px, 2.4vw, 38px);
  border: 1px solid var(--line);
  border-top: 4px solid var(--accent);
  border-radius: 14px;
  background: var(--panel);
}

/* The card itself now sets the measure, so the copy inside fills it. */
.coverage-col .legal-copy,
.policy-card .legal-copy {
  max-width: none;
  margin: 0;
}

.coverage-col-title {
  margin: 0 0 16px;
  color: var(--ink);
  font-size: clamp(1.2rem, 1.7vw, 1.55rem);
  line-height: 1.25;
}

.coverage-col.is-covered {
  border-top-color: #1a8f5e;
}

.coverage-col.is-excluded {
  border-top-color: #c23b3b;
}

/* The first sub-heading inside a card sits right under the card title, so it
   doesn't need the 34px of separation .legal-copy h3 normally gets. */
.coverage-col .legal-copy > h3:first-child,
.policy-card .legal-copy > h3:first-child {
  margin-top: 0;
}

/* "At a glance" summary above the full policy -- most visitors read only
   this, so it carries the four things that actually matter. Wider than the
   .legal-copy measure it sits inside, since these are short blocks side by
   side rather than running text. */
/* Sits inside .legal-copy, whose 78ch measure is meant for running text --
   these are four short cards in a row, so the grid escapes that cap and
   centres on the section instead. (An earlier version offset it with a
   negative-margin calculation, which only lined up at one window width.) */
.warranty-glance-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  width: min(1500px, 100%);
  margin-inline: auto;
}

.warranty-glance-card {
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: 12px;
  background: var(--panel);
}

.warranty-glance-card h4 {
  margin: 0 0 8px;
  color: var(--ink);
  font-size: 1rem;
}

.warranty-glance-card p {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.6;
}

.warranty-glance-card.is-covered {
  border-left-color: #1a8f5e;
}

.warranty-glance-card.is-excluded {
  border-left-color: #c23b3b;
}

@media screen and (max-width: 900px) {
  .warranty-glance-grid {
    margin-left: 0;
    width: 100%;
  }
}

/* An optional dated "last updated" line for a policy. Not currently used --
   kept because the warranty page may want one if the terms start changing
   and customers need to tell versions apart. */
.legal-updated {
  margin: -4px 0 26px;
  color: var(--muted);
  font-size: 0.88rem;
}

/* Downloads page "Configure & Download" heading -- centered and stacked
   instead of the shared class's left-eyebrow/right-heading row, same
   treatment as #from-solutions. */
#downloads-product-pdfs .section-heading {
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
}

/* Was a flat 1.6rem, which left it small against the full-width band it
   sits in. The floor here is 2.4rem -- 50% up on that -- and it scales
   with the viewport from there.

   The shared `.section-heading h2 { max-width: 780px }` is released too:
   at these sizes the line is wider than 780px, so the cap would have
   forced a wrap and kept the heading from reaching out to either side. */
#downloads-product-pdfs .section-heading h2 {
  max-width: none;
  font-size: clamp(2.4rem, 4.4vw, 3.6rem);
}

/* The eyebrow above it stayed at the shared 0.78rem, which read as a
   caption once the heading below grew. Scaled up to sit with it while
   staying clearly secondary -- it keeps the uppercase letter-spacing, so
   the tracking is eased slightly to stop it running long at this size. */
#downloads-product-pdfs .section-heading .eyebrow {
  font-size: clamp(1.05rem, 1.5vw, 1.4rem);
  letter-spacing: 0.1em;
}

#desktop-strengths .section-heading .eyebrow {
  font-size: 0.92rem;
}

#desktop-strengths .spec-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  max-width: 1800px;
  margin: 0 auto;
}

@media (max-width: 980px) {
  #desktop-strengths .spec-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  #desktop-strengths .spec-grid {
    grid-template-columns: 1fr;
  }
}

/* Real, named desktop models (LC7500A/LC5500A/LC3500A) -- horizontally
   scrollable row of 5 cards, replacing the old 3 fictional D100/D300/D500
   cards. Each card's "Configure This Model" button locks the interactive
   configurator below to that model's real brand/generation/chipset. */
.desktop-model-row {
  display: flex;
  gap: 18px;
  max-width: 1800px;
  margin: 0 auto;
  padding: 4px 4px 4px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  /* Still scrollable/draggable, just no visible scrollbar track --
     cards peeking at the edge signal there's more, like the reference. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.desktop-model-row::-webkit-scrollbar {
  display: none;
}

.desktop-model-loading {
  color: var(--muted);
  padding: 40px 0;
}

.desktop-model-card {
  position: relative;
  display: grid;
  gap: 14px;
  align-content: start;
  flex: 0 0 360px;
  min-height: 520px;
  padding: 24px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
  scroll-snap-align: start;
}

.desktop-model-card.selected {
  border-color: #03547f;
  box-shadow: var(--shadow);
}

.desktop-model-card h3 {
  margin: 0;
}

.desktop-model-tagline {
  margin: 0;
  color: var(--muted);
  line-height: 1.5;
}

.desktop-model-card .price {
  margin: 0;
  color: var(--accent-dark);
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  font-weight: 900;
  line-height: 1;
}

.desktop-model-specs {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 14px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.desktop-model-specs div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.88rem;
}

.desktop-model-specs dt {
  color: var(--muted);
}

.desktop-model-specs dd {
  margin: 0;
  text-align: right;
  font-weight: 600;
}

.desktop-model-card ul {
  display: grid;
  gap: 8px;
  margin: 0;
  padding-left: 20px;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

.desktop-model-select {
  width: 100%;
  margin-top: auto;
}

/* Bar shown above the customization form once a model card has been
   selected -- names the locked model and offers a way back to a free
   build. Hidden (is-hidden) until applyModelLock() runs. */
.model-lock-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
  padding: 14px 18px;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 8px;
}

.button.small {
  padding: 8px 14px;
  font-size: 0.85rem;
}

.configurator-section {
  color: #ffffff;
  background: #03547f;
}

.configurator-shell {
  max-width: 1800px;
  margin: 0 auto;
}

.configurator-intro {
  max-width: 820px;
  margin-bottom: 26px;
}

.configurator-section .eyebrow,
.configurator-section p {
  color: rgba(255, 255, 255, 0.78);
}

.configurator-section h2 {
  max-width: 760px;
}

.model-search-panel {
  position: relative;
  display: grid;
  gap: 22px;
  min-height: 292px;
  margin-bottom: 28px;
  padding: 28px;
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
}

.model-search-panel h3,
.config-block h3 {
  color: #ffffff;
}

.search-button {
  position: absolute;
  top: 70px;
  right: 24px;
  min-height: 38px;
  padding: 9px 16px;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.18);
  border: 0;
  border-radius: 8px;
  font-weight: 800;
  cursor: pointer;
}

.empty-search {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 10px;
  min-height: 140px;
  color: rgba(255, 255, 255, 0.78);
  text-align: center;
}

.empty-search span {
  width: 32px;
  height: 32px;
  border: 3px solid rgba(255, 255, 255, 0.72);
  border-radius: 999px;
  box-shadow: 18px 18px 0 -14px rgba(255, 255, 255, 0.72);
}

.empty-search small {
  color: rgba(255, 255, 255, 0.62);
  font-weight: 800;
}

.config-block {
  margin-top: 26px;
}

.config-block > p {
  margin: 8px 0 14px;
  font-weight: 700;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 14px;
}

.is-hidden {
  display: none !important;
}

.choice-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 42px;
  padding: 10px 16px;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid transparent;
  border-radius: 8px;
  font: inherit;
  font-weight: 850;
  cursor: pointer;
}

.choice-chip.selected {
  color: #03547f;
  background: #ffffff;
}

.choice-chip.disabled {
  color: rgba(255, 255, 255, 0.42);
  background: rgba(255, 255, 255, 0.08);
}

.choice-chip small {
  display: block;
  margin-left: 6px;
  color: #6ff0ab;
  font-weight: 900;
}

.choice-chip.selected small {
  color: #03547f;
}

.config-divider {
  height: 2px;
  margin: 28px 0;
  background: rgba(255, 255, 255, 0.26);
}

.option-grid {
  display: grid;
  gap: 14px;
  margin-top: 14px;
}

.option-grid.two-col {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.option-grid.three-col {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* Interactive Panel screen sizes -- all four on one row rather than the
   2x2 the shared .two-col class produces. Scoped by id (which outranks
   .option-grid.two-col on specificity) because that class is shared by
   27 other option grids across the configurators, none of which should
   change. Applies to both copies of the configurator page, since they use
   the same id. */
#panel-screen-size-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 1100px) {
  #panel-screen-size-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  #panel-screen-size-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Digital Signage category and screen-size pickers.
   These lists are short and variable (2 categories; 2-6 sizes depending on
   the type chosen), and .two-col stretched each card across half the page.
   auto-fill is the key: it lays down as many ~240px tracks as fit and
   LEAVES the spare ones empty, so two items stay two normal-sized cards
   instead of expanding to fill the row -- which auto-fit or a fixed column
   count would both do. */
#signage-category-grid,
#signage-screen-size-grid {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

/* Slightly tighter than the default config card, since these carry only a
   short label plus one line ("2 types available" / "Model: F3285TP"). */
#signage-category-grid .config-card-head,
#signage-screen-size-grid .config-card-head {
  padding: 12px 14px;
}

#signage-category-grid .mini-specs,
#signage-screen-size-grid .mini-specs {
  padding: 10px 14px;
}

@media (max-width: 560px) {
  #signage-category-grid,
  #signage-screen-size-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Chipset/motherboard cards can grow taller when a card's I/O Ports toggle is
   expanded (see .io-ports-toggle above). Grid items stretch to match the
   tallest sibling in their row by default -- override that here so expanding
   one card's I/O Ports never stretches/distorts the other cards in the row. */
#chipset-grid,
#motherboard-grid {
  align-items: start;
}

.config-card {
  overflow: hidden;
  width: 100%;
  padding: 0;
  color: #ffffff;
  background: rgba(0, 31, 49, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 8px;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.choice-chip:focus-visible,
.config-card:focus-visible,
.search-button:focus-visible,
.peripheral-card button:focus-visible,
.io-toggle:focus-visible {
  outline: 3px solid rgba(255, 255, 255, 0.88);
  outline-offset: 3px;
}

.config-card.selected {
  background: #03547f;
  border-color: #ffffff;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.42);
}

.config-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 15px 16px;
  background: rgba(255, 255, 255, 0.12);
}

.config-card-head strong {
  position: relative;
  padding-left: 24px;
}

.config-card-head strong::before {
  position: absolute;
  top: 50%;
  left: 0;
  width: 12px;
  height: 12px;
  content: "";
  background: #79b9d5;
  border-radius: 999px;
  transform: translateY(-50%);
}

.config-card.selected .config-card-head strong::before {
  background: #ffffff;
}

.config-card-head span {
  color: #ff9a9a;
  font-size: 0.86rem;
  font-weight: 900;
  white-space: nowrap;
}

.mini-specs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  padding: 16px;
}

.mini-specs.two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.mini-specs.three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.mini-specs span {
  color: #ffffff;
  font-weight: 900;
}

.mini-specs small {
  display: block;
  margin-bottom: 4px;
  color: rgba(255, 255, 255, 0.58);
  font-weight: 800;
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 16px 16px;
}

.tag-row span {
  padding: 5px 9px;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.12);
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 800;
}

.io-ports-block {
  display: block;
  padding: 0 16px 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.io-ports-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-top: 14px;
  padding-bottom: 4px;
  cursor: pointer;
}

.io-ports-toggle:focus-visible {
  outline: 3px solid rgba(255, 255, 255, 0.88);
  outline-offset: 3px;
}

.io-ports-heading {
  display: block;
  color: rgba(255, 255, 255, 0.58);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.io-ports-arrow {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-right: 2px solid rgba(255, 255, 255, 0.58);
  border-bottom: 2px solid rgba(255, 255, 255, 0.58);
  transform: rotate(45deg);
  transition: transform 0.18s ease;
}

.io-ports-toggle.expanded .io-ports-arrow {
  transform: rotate(-135deg);
}

.io-ports-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-top: 10px;
}

.io-ports-col {
  display: block;
}

.io-ports-col small {
  display: block;
  margin-bottom: 6px;
  color: #79b9d5;
  font-size: 0.78rem;
  font-weight: 900;
}

.io-ports-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.io-ports-list span {
  display: block;
  color: #ffffff;
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.4;
}

.config-card p,
.config-card-copy {
  display: block;
  margin: 0;
  padding: 16px;
  color: rgba(255, 255, 255, 0.84);
  font-weight: 750;
  line-height: 1.55;
}

.config-card.compact {
  min-height: 116px;
}

.psu-grid .config-card.compact {
  min-height: 112px;
}

.peripheral-select-card {
  display: flex;
  flex-direction: column;
}

.peripheral-detail-link {
  display: inline-block;
  margin-top: 8px;
  padding: 0 2px;
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.82rem;
  font-weight: 800;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.peripheral-detail-link:hover,
.peripheral-detail-link:focus-visible {
  color: #ffffff;
}

.option-stack {
  display: grid;
  gap: 8px;
  max-width: 380px;
  margin-top: 14px;
}

.ram-card {
  padding-bottom: 14px;
}

.ram-card p {
  padding: 14px 16px 0;
  font-size: 0.82rem;
}

.peripheral-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  margin-top: 14px;
}

.peripheral-card {
  min-height: 96px;
  padding: 16px;
  background: rgba(255, 255, 255, 0.12);
  border-radius: 8px;
}

.peripheral-card strong {
  display: inline-block;
  margin-bottom: 18px;
}

.peripheral-card button {
  float: right;
  min-height: 30px;
  padding: 7px 14px;
  color: #33415c;
  background: #ffffff;
  border: 0;
  border-radius: 8px;
  font-weight: 900;
  cursor: pointer;
}

.peripheral-card p {
  clear: both;
  margin: 0;
  color: rgba(255, 255, 255, 0.62);
  font-weight: 800;
}

.summary-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 0.9fr);
  gap: 24px;
  padding: 24px;
  background: rgba(255, 255, 255, 0.12);
  border-radius: 8px;
}

.summary-panel dl {
  display: grid;
  gap: 12px;
  margin: 20px 0 0;
}

.summary-panel dl div {
  display: grid;
  grid-template-columns: 170px minmax(0, 1fr);
  gap: 20px;
}

.summary-panel dt {
  color: rgba(255, 255, 255, 0.82);
  font-weight: 850;
}

.summary-panel dd {
  margin: 0;
  color: #ffffff;
  font-weight: 900;
  text-align: right;
}

.io-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 34px;
  margin-top: 14px;
  padding: 0 14px;
  color: #ffffff;
  text-align: left;
  background: rgba(0, 31, 49, 0.34);
  border: 0;
  border-radius: 8px;
  font-weight: 900;
  cursor: pointer;
}

.io-toggle-label {
  flex: 1 1 auto;
}

.io-toggle-arrow {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-right: 2px solid rgba(255, 255, 255, 0.72);
  border-bottom: 2px solid rgba(255, 255, 255, 0.72);
  transform: rotate(45deg);
  transition: transform 0.18s ease;
}

.io-toggle.expanded .io-toggle-arrow {
  transform: rotate(-135deg);
}

.io-toggle-panel {
  margin-top: 10px;
  padding: 14px;
  background: rgba(0, 31, 49, 0.34);
  border-radius: 8px;
}

.io-toggle-panel .io-ports-cols {
  margin-top: 0;
}

.quote-panel {
  display: grid;
  align-content: center;
  gap: 12px;
  padding-left: 24px;
  border-left: 2px solid rgba(255, 255, 255, 0.42);
}

.breakdown {
  padding: 22px;
  background: rgba(0, 31, 49, 0.54);
  border-radius: 8px;
}

.breakdown strong {
  display: block;
  padding-bottom: 16px;
  border-bottom: 2px solid rgba(255, 255, 255, 0.18);
}

.breakdown div {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  margin-top: 12px;
  font-weight: 900;
}

.breakdown .offer-row {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 2px solid rgba(255, 255, 255, 0.18);
}

.breakdown b {
  font-size: 1rem;
}

.breakdown .offer-row b {
  font-size: 1.5rem;
}

.comparison-section {
  background: var(--paper);
}

.compare-table-wrap {
  max-width: 1800px;
  margin: 0 auto;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #ffffff;
}

.compare-table {
  width: 100%;
  min-width: 760px;
  border-collapse: collapse;
}

.compare-table th,
.compare-table td {
  padding: 16px;
  text-align: left;
  border-bottom: 1px solid var(--line);
}

.compare-table th {
  color: var(--accent-dark);
  background: #f0f7f4;
  font-size: 0.92rem;
}

.compare-table td:first-child {
  font-weight: 800;
}

.compare-table tr:last-child td {
  border-bottom: 0;
}

.split-band {
  display: grid;
  grid-template-columns: minmax(240px, 0.74fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 72px);
  background: linear-gradient(90deg, #edf7fa, var(--sky));
}

/* Grid items stretch to the row height by default, so the heading column
   filled the full height of the (taller) card column and its text sat at
   the top -- reading as top-aligned against a much deeper block of cards.
   Centering just this column vertically; the cards column is left as
   `stretch` so the cards keep their equal heights. */
.split-band > div:first-child {
  align-self: center;
}

/* The band collapses to one column at 980px (the earlier of the two
   responsive passes that list .split-band), so from there down the heading
   stops being a narrow left rail beside the cards and becomes a full-width
   block on its own -- left-aligned it read as if it had drifted off to one
   side. Centering it for exactly the stacked state; the two-column desktop
   layout above 980px is untouched. The cards below stay left-aligned,
   matching the section headings on the product pages. */
@media (max-width: 980px) {
  .split-band > div:first-child {
    text-align: center;
  }
}

.feature-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

/* Used when .feature-list appears on its own under a .section-heading
   (not inside .split-band, which already constrains its own width) --
   keeps the card grid aligned with the heading above it instead of
   free-flowing to the section's full padded width. */
.feature-grid {
  max-width: 1800px;
  margin: 0 auto;
}

/* Blog post body copy -- a narrower, readable column instead of the
   full section width used by hero/grid content. */
.blog-post {
  max-width: 720px;
  margin: 0 auto;
}

.blog-post h2 {
  margin-top: 2em;
}

.blog-post p,
.blog-post li {
  color: var(--muted);
  line-height: 1.7;
  margin-bottom: 1.1em;
}

.blog-post ul,
.blog-post ol {
  padding-left: 1.4em;
}

.blog-meta {
  color: var(--muted);
  font-size: 0.92rem;
  margin-bottom: 2em;
}

.feature-list article {
  min-height: 180px;
  padding: 22px;
  background: rgba(255, 255, 255, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.72);
  border-radius: 8px;
}

.feature-list h3 {
  margin-bottom: 10px;
}

.spec-band {
  display: grid;
  grid-template-columns: minmax(240px, 0.72fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 72px);
  background: #ffffff;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.spec-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.spec-grid article {
  min-height: 150px;
  padding: 20px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
}

.spec-grid strong {
  display: block;
  margin-bottom: 8px;
  color: var(--accent-dark);
  font-size: 1rem;
}

.spec-grid p {
  margin: 0;
  color: var(--muted);
  line-height: 1.62;
}

/* About page hero -- image full-bleed edge-to-edge, with the text
   overlaid directly on top of it (in the photo's own empty left side)
   instead of sitting in a separate block below. */
/* The photo used to size this section: the <img> was in flow at
   `height: auto`, and the copy was absolutely positioned on top of it. So
   the section's height was always width / 2.572 (the photo's own ratio)
   while the copy's height was set by its text -- and text doesn't shrink
   nearly as fast as that. Below roughly 1050px the copy was taller than the
   box and `overflow: hidden` sliced it off, top and bottom.

   The roles are swapped: the copy is in flow and sets the height, the photo
   is absolutely positioned behind it and covers whatever box results. The
   min-height keeps the photo at its own proportions whenever the copy fits
   inside them, so a wide screen looks exactly as it did; when the copy
   needs more room the section grows and the photo crops instead of the
   text. 38.5vw rather than the exact 38.87% (650/1672) because vw counts
   the scrollbar -- undershooting slightly keeps any residual crop vertical
   over the out-of-focus background rather than horizontal. */
#about-hero {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  min-height: 38.5vw;
}

#about-hero .about-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

/* Anchored right: once the section is taller than the photo's own ratio,
   `cover` scales to height and trims the sides. Centered, that took the
   "ABOUT US" dice -- the subject, and the only thing on the right-hand
   side -- off the edge. Anchoring right keeps them whole and takes the
   trim out of the foliage on the left instead, which is out of focus and
   loses nothing. It has no effect at widths where there's no side crop. */
#about-hero .about-hero-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: right center;
}

#about-hero .about-hero-copy-wrap {
  position: relative;
  z-index: 1;
  width: 100%;
  display: flex;
  align-items: center;
  padding: clamp(18px, 4vw, 64px);
}

/* Reuses the homepage's own "Made in India" text/badge/button styling
   (.hero-slide-primary + hero-copy/hero-trust-badges/hero-actions)
   verbatim, but without that class's dark panel background -- per
   request, no solid/dark backing here, just the text straight over the
   photo. A text-shadow (rather than a background) keeps it legible over
   the photo's lighter, busier areas. */
#about-hero .about-hero-primary {
  max-width: none;
  background: none;
}

/* Center the copy within its own left-hand column -- same treatment as the
   support and signage heroes. The column doesn't move: .hero-copy stays at
   the left of the frame at its 760px cap, well clear of the dice, and only
   the text inside it is centered.

   The auto margins matter as much as `text-align` here: the h1 and the
   paragraph carry their own ch-based caps (32ch and 62ch), which fall
   inside 760px at the smaller type sizes -- and a narrower block with
   `margin: 0` would sit hard left with only its text centered within it. */
#about-hero .about-hero-copy-wrap .hero-copy {
  text-align: center;
}

#about-hero .about-hero-copy-wrap .hero-copy h1,
#about-hero .about-hero-copy-wrap .hero-copy > p {
  margin-left: auto;
  margin-right: auto;
}

#about-hero .about-hero-copy-wrap .hero-trust-badges,
#about-hero .about-hero-copy-wrap .hero-actions {
  justify-content: center;
}

/* White text on the photo. There's no solid panel behind it (that's
   deliberate), so legibility comes from the shadow rather than a
   background: a tight dark halo to hold the letterforms against the
   brightest highlights in the foliage, plus a wider soft one that acts as
   a faint drop shadow over the mid-tones. */
#about-hero .about-hero-primary .hero-copy h1,
#about-hero .about-hero-primary .hero-copy > p {
  color: #fff;
  text-shadow: 0 1px 3px rgba(12, 20, 16, 0.6), 0 0 16px rgba(12, 20, 16, 0.45);
}

#about-hero .about-hero-primary .hero-trust-badge {
  color: #fff;
  text-shadow: 0 1px 3px rgba(12, 20, 16, 0.65);
}

#about-hero .about-hero-primary .hero-trust-badge:not(:first-child) {
  border-left-color: rgba(255, 255, 255, 0.45);
}

/* .hero-slide-primary's secondary-button override makes it a transparent
   white-outline button, meant for its own solid dark panel -- against a
   photo that reads too faint, so bring it back to the normal solid
   white/dark-text button here. */
#about-hero .about-hero-primary .button.secondary {
  color: var(--accent-dark);
  background: #fff;
  border-color: var(--line);
}

/* Bigger than the homepage carousel's own sizing for all of this panel's
   text and buttons -- scoped here only, so the homepage hero is untouched. */
#about-hero .about-hero-primary .hero-copy h1 {
  max-width: none;
  font-size: clamp(3rem, 5.8vw, 5.2rem);
  white-space: nowrap;
}

#about-hero .about-hero-primary .hero-copy > p {
  font-size: clamp(1.35rem, 2.1vw, 1.7rem);
}

#about-hero .about-hero-primary .hero-trust-badge {
  font-size: clamp(1.2rem, 1.9vw, 1.5rem);
}

#about-hero .about-hero-primary .button {
  min-height: 62px;
  padding: 16px 34px;
  font-size: 1.35rem;
}

/* About page sections (What We Do through Who We Serve) -- bump the
   eyebrow up and bring the heading down from the shared clamp(2rem,4vw,
   3.5rem) default, since these headings are full descriptive sentences
   rather than the 2-3 word headings that size was tuned for. */
#about-what-we-do .section-heading .eyebrow,
#about-mission-vision .section-heading .eyebrow,
#about-why-choose .section-heading .eyebrow,
#about-values .section-heading .eyebrow,
#about-who-we-serve .section-heading .eyebrow {
  font-size: 1.1rem;
}

#about-what-we-do .section-heading h2,
#about-mission-vision .section-heading h2,
#about-why-choose .section-heading h2,
#about-values .section-heading h2,
#about-who-we-serve .section-heading h2 {
  font-size: 1.9rem;
}

/* About page "Why Choose Litset" -- reuses the .spec-grid card look but at
   4 columns like #desktop-strengths, since 8 short feature cards read
   better as two rows of four than the base 2-column layout. */
#about-why-choose .spec-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  max-width: 1800px;
  margin: 0 auto;
}

@media (max-width: 980px) {
  #about-why-choose .spec-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  #about-why-choose .spec-grid {
    grid-template-columns: 1fr;
  }
}

/* About page "Our Core Values" -- same .spec-grid card look at 3 columns
   so 5 short value cards wrap 3+2 instead of the base 2-column layout. */
#about-values .spec-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  max-width: 1800px;
  margin: 0 auto;
}

@media (max-width: 980px) {
  #about-values .spec-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  #about-values .spec-grid {
    grid-template-columns: 1fr;
  }
}

/* About page "Mission & Vision" -- two large cards, same bordered/paper
   card treatment as .spec-grid but roomier since each holds a full
   paragraph rather than a one-line description. */
.mission-vision-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  max-width: 1800px;
  margin: 0 auto;
}

.mission-vision-grid article {
  padding: 32px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
}

.mission-vision-grid h3 {
  margin: 0 0 12px;
  color: var(--accent-dark);
}

.mission-vision-grid p {
  margin: 0;
  color: var(--muted);
  line-height: 1.7;
}

@media (max-width: 720px) {
  .mission-vision-grid {
    grid-template-columns: 1fr;
  }
}

/* About page "Who We Serve" -- centers the industries-chip row under its
   own section-heading instead of the left-aligned placement used inside
   the homepage Industries panel. */
/* About page "Who We Serve" -- bigger pill chips than the homepage
   Industries panel's version, arranged as a staggered honeycomb (4 across
   the top row, then 2 more centered in the gaps below) instead of a
   plain wrapped row. An 8-column grid makes this easy: each top-row chip
   spans 2 columns (1-2, 3-4, 5-6, 7-8), and each bottom-row chip spans
   the 2 columns straddling the gap between two top-row chips (2-3, 6-7). */
#about-who-we-serve .industries-chips {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 24px 18px;
  justify-items: stretch;
  max-width: 1800px;
  margin: 28px auto 0;
}

#about-who-we-serve .industries-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 26px 20px;
  font-size: 1.4rem;
  text-align: center;
  line-height: 1.25;
}

/* grid-row is pinned explicitly on every chip here -- without it, the
   grid auto-placement cursor (which only moves forward, never backtracks
   within a row) pushes chip 7 down onto a 3rd line: by the time it's
   placed, chips 5 and 6 have already advanced the cursor past column 4,
   so chip 7's earlier column 4/6 span no longer fits row 2 and it
   overflows to row 3. Pinning rows 1 and 2 directly sidesteps that. */
#about-who-we-serve .industries-chip:nth-child(1) { grid-column: 1 / 3; grid-row: 1; }
#about-who-we-serve .industries-chip:nth-child(2) { grid-column: 3 / 5; grid-row: 1; }
#about-who-we-serve .industries-chip:nth-child(3) { grid-column: 5 / 7; grid-row: 1; }
#about-who-we-serve .industries-chip:nth-child(4) { grid-column: 7 / 9; grid-row: 1; }
#about-who-we-serve .industries-chip:nth-child(5) { grid-column: 2 / 4; grid-row: 2; }
#about-who-we-serve .industries-chip:nth-child(6) { grid-column: 6 / 8; grid-row: 2; }
#about-who-we-serve .industries-chip:nth-child(7) { grid-column: 4 / 6; grid-row: 2; }

@media (max-width: 900px) {
  #about-who-we-serve .industries-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
  }

  #about-who-we-serve .industries-chip {
    grid-column: auto;
  }
}

.cta-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: clamp(42px, 6vw, 76px) clamp(18px, 4vw, 64px);
  color: #fff;
  background: #03547f;
}

.cta-band h2 {
  max-width: 720px;
}

/* Reusable centered/stacked variant of .cta-band -- same treatment as
   #desktop-cta on the Desktop PCs page, applied via an extra class so any
   plain "eyebrow + heading + copy + single button" CTA band can opt in
   without a one-off id + duplicate CSS block per page. */
.cta-band-centered {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

.cta-band-centered > div {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.cta-band-centered h2 {
  max-width: 960px;
  margin: 0 auto;
}

/* Doubled-up selector (0,2,0) on purpose. This band was relying on
   `.cta-band { align-items: center }` to center the button, but the
   responsive pass further down the file sets `.cta-band { align-items:
   flex-start }` below 720px -- equal specificity, later in the file, so it
   won, and the button dropped to the left while the text above it stayed
   centered. There was already a `@media (max-width: 720px)
   .cta-band-centered` override here trying to fix exactly that, but it sat
   *earlier* in the file than the rule it was meant to beat, so it never
   applied. Matching both classes wins on specificity instead of order, at
   every width. */
.cta-band.cta-band-centered,
.cta-band.keyboard-cta,
.cta-band.monitor-cta,
.cta-band.mouse-cta {
  align-items: center;
}

.cta-band p,
.cta-band .eyebrow {
  color: rgba(255, 255, 255, 0.74);
}

/* Support page "Have a Specific Question?" CTA -- centered/stacked instead
   of the shared class's left-text/right-button row, same treatment as
   #desktop-cta on the Desktop PCs page. */
#support-cta {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

#support-cta > div {
  display: flex;
  flex-direction: column;
  align-items: center;
}

#support-cta h2 {
  max-width: 960px;
  margin: 0 auto;
}

@media (max-width: 720px) {
  #support-cta {
    align-items: center;
  }
}

/* Desktop Rollout CTA -- centered/stacked instead of the shared class's
   left-text/right-button row, scoped to this section only (the shared
   .cta-band class is reused as a left-aligned row on many other pages). */
#desktop-cta {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

#desktop-cta > div {
  display: flex;
  flex-direction: column;
  align-items: center;
}

#desktop-cta h2 {
  max-width: 960px;
  margin: 0 auto;
}

@media (max-width: 720px) {
  #desktop-cta {
    align-items: center;
  }
}

/* Become a Dealer page "Not Ready to Apply?" CTA -- centered/stacked instead
   of the shared class's left-text/right-button row, same treatment as
   #desktop-cta on the Desktop PCs page. */
#dealer-cta {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

#dealer-cta > div {
  display: flex;
  flex-direction: column;
  align-items: center;
}

#dealer-cta h2 {
  max-width: 960px;
  margin: 0 auto;
}

@media (max-width: 720px) {
  #dealer-cta {
    align-items: center;
  }
}

/* Software page "Building a Quote?" CTA -- centered/stacked instead of the
   shared class's left-text/right-button row, same treatment as #desktop-cta
   on the Desktop PCs page. */
#software-cta {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

#software-cta > div {
  display: flex;
  flex-direction: column;
  align-items: center;
}

#software-cta h2 {
  max-width: 960px;
  margin: 0 auto;
}

@media (max-width: 720px) {
  #software-cta {
    align-items: center;
  }
}

/* Solutions page hero -- smaller than the shared h1 default (which was
   sized for much shorter headlines) so this longer headline reads as a
   normal hero size instead of overflowing/wrapping awkwardly. */
#solutions-hero .hero-copy h1 {
  max-width: 18ch;
  font-size: clamp(2.2rem, 4vw, 3.4rem);
  line-height: 1.12;
}

/* Downloads page hero -- a single self-contained promo banner image (its
   own "Get a quotation PDF..." heading, copy, and feature icons are
   already baked into the graphic), same treatment as #dealer-hero and
   #careers-hero. Source graphic is already pre-cropped to the right
   ratio, so it's shown as-is with no further object-fit cropping. */
/* Taller band. The banner is a single fixed 1672x696 composition with the
   headline hard against the top edge and the icon row against the bottom,
   so the height can't come from cropping to a taller ratio -- `cover` would
   have to trim the sides, and the headline is on one side and the quotation
   sheet on the other.

   The space is added around the artwork instead, over a background matched
   to the graphic's own edges: sampled, its top row averages #ebecf0 and its
   bottom row #d1d2d8, so the gradient runs between those two and the joins
   are invisible. More is added above than below -- the headline is the part
   that was short of room, and the top edge of the graphic is a clean flat
   tone while the bottom carries the dot pattern and swirls, which a wide
   band beneath would only draw attention to. */
#downloads-hero {
  overflow: hidden;
  padding-top: clamp(28px, 5vw, 90px);
  padding-bottom: clamp(18px, 3vw, 54px);
  background: linear-gradient(
    180deg,
    #ebecf0 0%,
    #ebecf0 25%,
    #e2e3e9 65%,
    #d1d2d8 100%
  );
}

#downloads-hero img {
  display: block;
  width: 100%;
  height: auto;
}

/* .product-hero (shared) sets min-height: calc(100vh - 88px) for a
   full-viewport look on product pages -- shrink this one back down since
   its content (headline + short copy + buttons) doesn't need that much
   vertical space. */
#solutions-hero {
  min-height: auto;
  padding-top: clamp(56px, 8vw, 100px);
  padding-bottom: clamp(56px, 8vw, 100px);
}

/* Solutions page "Planning a Rollout?" CTA -- centered/stacked instead of
   the shared class's left-text/right-button row, same treatment as
   #desktop-cta on the Desktop PCs page. */
#solutions-cta {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

#solutions-cta > div {
  display: flex;
  flex-direction: column;
  align-items: center;
}

#solutions-cta h2 {
  max-width: 960px;
  margin: 0 auto;
}

@media (max-width: 720px) {
  #solutions-cta {
    align-items: center;
  }
}

/* Solutions page -- "What We Do" intro block. Just a centered heading and
   a single paragraph (no eyebrow, no grid), so the shared .section-heading
   row is recentered the same way #from-blog does it on the homepage. */
/* Solutions page -- "What We Do" intro, styled as its own bordered box
   sitting directly on top of the category grid below (same border color/
   width, no gap, no border-bottom of its own -- the grid's own first-row
   border-top supplies that shared line) so the two read as one connected
   frame. */
.solutions-intro {
  max-width: 1800px;
  margin: 0 auto;
  padding: 40px clamp(18px, 4vw, 64px);
  border: 1px solid rgba(20, 32, 29, 0.4);
  border-bottom: none;
  text-align: center;
}

.solutions-intro h2 {
  margin: 0 0 14px;
}

.solutions-intro p {
  max-width: 760px;
  margin: 0 auto;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1.7;
}

/* Solutions page -- category grid. Press-style tile grid (image, small
   tag, bold headline, CTA, folded-corner accent) instead of the shared
   .product-card look -- scoped entirely to its own classes (.solution-tile
   etc.), not the shared .product-card, since nothing else on the site
   should pick up this treatment. Keeps the page's normal light background;
   only the grid layout/tile styling is different from a standard card. */
#solutions-categories {
  padding: clamp(52px, 8vw, 104px) clamp(18px, 4vw, 64px);
}

.solutions-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  max-width: 1800px;
  margin: 0 auto;
}

.solution-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  border-right: 1px solid rgba(20, 32, 29, 0.4);
  border-bottom: 1px solid rgba(20, 32, 29, 0.4);
  overflow: hidden;
  text-decoration: none;
  transition: background 180ms ease;
}

/* Top and left edges of the grid come from the tiles themselves (first
   row / first column) rather than the .solutions-grid container's own
   border -- keeps every edge pixel-aligned to the tiles regardless of the
   container's own padding. */
.solution-tile:nth-child(-n + 3) {
  border-top: 1px solid rgba(20, 32, 29, 0.4);
}

.solution-tile:nth-child(3n + 1) {
  border-left: 1px solid rgba(20, 32, 29, 0.4);
}

.solution-tile:hover {
  background: var(--paper);
}

.solution-tile-media {
  aspect-ratio: 16 / 10;
  overflow: hidden;
  padding: 14px;
}

.solution-tile-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
}

.solution-tile-body {
  position: relative;
  flex: 1;
  display: grid;
  align-content: start;
  gap: 10px;
  padding: 18px 24px 56px;
}

.solution-tile-tag {
  margin: 0;
  color: var(--accent-dark);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.solution-tile-body h3 {
  margin: 0;
  color: var(--ink);
  font-size: 1.28rem;
  line-height: 1.26;
}

.solution-tile-body > p {
  margin: 0;
  color: var(--muted);
  line-height: 1.6;
}

.solution-products {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
}

.solution-products li {
  position: relative;
  padding-left: 12px;
  color: var(--muted);
  font-size: 0.85rem;
}

.solution-products li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent-dark);
}

.solution-tile-cta {
  position: absolute;
  left: 24px;
  bottom: 20px;
  color: var(--accent-dark);
  font-weight: 700;
  font-size: 0.9rem;
}

.solution-tile-corner {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 32px;
  height: 32px;
  background: var(--paper);
  border-top: 1px solid rgba(20, 32, 29, 0.4);
  border-left: 1px solid rgba(20, 32, 29, 0.4);
  clip-path: polygon(100% 0, 0% 100%, 100% 100%);
}

@media (max-width: 900px) {
  .solutions-grid {
    grid-template-columns: 1fr;
  }

  /* Single column now, so every tile is both "first row" and "first
     column" -- only the very first tile should get the top/left edges. */
  .solution-tile:nth-child(-n + 3) {
    border-top: none;
  }

  .solution-tile:nth-child(3n + 1) {
    border-left: none;
  }

  .solution-tile:first-child {
    border-top: 1px solid rgba(20, 32, 29, 0.4);
    border-left: 1px solid rgba(20, 32, 29, 0.4);
  }
}

/* Product listing page "Need Help Choosing?" CTA -- centered/stacked
   instead of the shared class's left-text/right-button row, same
   treatment as #desktop-cta on the Desktop PCs page. */
#product-cta {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

#product-cta > div {
  display: flex;
  flex-direction: column;
  align-items: center;
}

#product-cta h2 {
  max-width: 960px;
  margin: 0 auto;
}

@media (max-width: 720px) {
  #product-cta {
    align-items: center;
  }
}

/* Homepage "Need Help Choosing?" CTA -- centered/stacked instead of the
   shared class's left-text/right-button row, same treatment as #desktop-cta
   on the Desktop PCs page. */
#home-cta {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

#home-cta > div {
  display: flex;
  flex-direction: column;
  align-items: center;
}

#home-cta h2 {
  max-width: 960px;
  margin: 0 auto;
}

@media (max-width: 720px) {
  #home-cta {
    align-items: center;
  }
}

.usp-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(18px, 4vw, 40px);
  padding: 22px clamp(18px, 4vw, 64px);
  background: var(--sky);
  border-top: 1px solid var(--line);
}

.usp-item {
  display: flex;
  align-items: center;
  gap: 12px;
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--ink);
}

.usp-icon {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  color: var(--accent);
}

.usp-icon svg {
  width: 22px;
  height: 22px;
}

.site-footer {
  background: #2e3335;
  color: rgba(255, 255, 255, 0.82);
  border-top: none;
}

.footer-top {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(28px, 5vw, 64px);
  padding: 48px clamp(18px, 4vw, 64px) 36px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.footer-contact {
  display: flex;
  flex: 0 0 320px;
  flex-direction: column;
  gap: 7px;
  padding-right: clamp(24px, 4vw, 48px);
  border-right: 1px solid rgba(255, 255, 255, 0.14);
}

.footer-contact .brand-mark {
  height: 34px;
  width: auto;
  border-radius: 6px;
}

.footer-tagline {
  margin: 10px 0 8px;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.88rem;
}

.footer-contact h3 {
  margin: 10px 0 0;
  color: rgba(255, 255, 255, 0.55);
  font-size: 0.76rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.footer-contact-label {
  margin: 12px 0 2px;
  color: rgba(255, 255, 255, 0.5);
  font-size: 0.78rem;
}

.footer-contact a,
.footer-contact p {
  margin: 0;
  color: #fff;
  font-size: 0.92rem;
}

.footer-col-group {
  display: flex;
  flex: 1;
  flex-wrap: wrap;
  gap: clamp(24px, 4vw, 56px);
}

.footer-col {
  display: flex;
  flex: 1;
  min-width: 160px;
  flex-direction: column;
  gap: 12px;
}

.footer-col h4 {
  margin: 0 0 4px;
  color: #fff;
  font-size: 0.95rem;
}

.footer-col a {
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.92rem;
  font-weight: 600;
}

.footer-col a:hover {
  color: #fff;
}

.footer-social {
  display: flex;
  justify-content: center;
  gap: 14px;
  padding: 26px clamp(18px, 4vw, 64px);
}

.footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 50%;
  color: rgba(255, 255, 255, 0.75);
}

.footer-social a:hover {
  color: var(--ink);
  background: #fff;
  border-color: #fff;
}

.footer-social svg {
  width: 18px;
  height: 18px;
}

.footer-legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 18px clamp(18px, 4vw, 64px) 26px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.55);
  font-size: 0.82rem;
}

.footer-legal a {
  color: rgba(255, 255, 255, 0.7);
  font-weight: 600;
}

.footer-legal a:hover {
  color: #fff;
}

@media (max-width: 860px) {
  .footer-top {
    flex-direction: column;
  }

  .footer-contact {
    flex: none;
    padding-right: 0;
    padding-bottom: 24px;
    border-right: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.14);
  }
}

/* All-in-One PC page */
.aio-page {
  background: #eef3f6;
}

.aio-hero {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(360px, 1.1fr);
  gap: clamp(32px, 6vw, 88px);
  align-items: center;
  min-height: calc(100vh - 88px);
  padding: clamp(36px, 6vw, 80px) clamp(18px, 4vw, 64px);
  background: #fff;
  /* Clips the scroll-zoom image's zoomed-in state -- see scroll-zoom.js.
     Doesn't affect layout/spacing. */
  overflow: hidden;
}

.aio-hero .breadcrumb {
  grid-column: 1 / -1;
  width: 100%;
  margin: 0;
}

.aio-hero h1 {
  max-width: 10ch;
  font-size: clamp(3rem, 6.8vw, 6rem);
}

.aio-hero > div > p:not(.eyebrow) {
  max-width: 58ch;
  color: var(--muted);
  font-size: 1.06rem;
  line-height: 1.7;
}

.aio-hero > img,
.aio-showcase > img {
  width: 100%;
  height: 100%;
  max-height: 610px;
  object-fit: cover;
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.aio-series-section,
.aio-feature-section,
.aio-specs-section,
.aio-reviews {
  max-width: 1800px;
  margin: 0 auto;
}

.aio-series-picker {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  padding: 22px;
  background: #dce5eb;
  border-radius: 8px 8px 0 0;
}

.aio-series-card {
  display: grid;
  grid-template-columns: 42px 1fr;
  gap: 12px;
  min-height: 150px;
  padding: 20px;
  color: #33415c;
  text-align: left;
  background: #f8fafb;
  border: 2px solid transparent;
  border-radius: 8px;
  cursor: pointer;
}

.aio-series-card.selected {
  color: #fff;
  background: #03547f;
  border-color: #86d8f5;
  box-shadow: 0 10px 26px rgba(3, 84, 127, 0.24);
}

.aio-series-card > span:last-child {
  display: grid;
  align-content: start;
  gap: 7px;
}

.aio-series-card strong {
  font-size: 1.35rem;
}

.aio-series-card small {
  color: inherit;
  opacity: 0.76;
  line-height: 1.45;
}

.aio-series-icon {
  position: relative;
  width: 32px;
  height: 24px;
  margin-top: 3px;
  border: 2px solid currentColor;
  border-radius: 3px;
}

.aio-series-icon::after {
  position: absolute;
  bottom: -7px;
  left: 8px;
  width: 13px;
  content: "";
  border-bottom: 2px solid currentColor;
}

.aio-series-status {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 22px;
  color: #fff;
  background: #263e4c;
  border-radius: 0 0 8px 8px;
}

.aio-series-status div {
  display: grid;
}

.aio-series-status small {
  opacity: 0.7;
}

.aio-series-status a {
  margin-left: auto;
  font-weight: 850;
}

.status-check {
  display: grid;
  width: 32px;
  height: 32px;
  place-items: center;
  background: #03547f;
  border-radius: 50%;
}

.aio-showcase {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(340px, 0.86fr);
  gap: clamp(28px, 5vw, 72px);
  max-width: 1800px;
  margin: 0 auto;
  color: #fff;
  background: #03547f;
  border-radius: 8px;
  /* Clips the scroll-zoom image's zoomed-in state to the card's rounded
     corners -- see scroll-zoom.js. Doesn't affect layout/spacing. */
  overflow: hidden;
}

.aio-showcase-copy > p:not(.eyebrow, .aio-showcase-price) {
  max-width: 58ch;
  color: rgba(255, 255, 255, 0.78);
  line-height: 1.65;
}

.aio-showcase .eyebrow {
  color: rgba(255, 255, 255, 0.76);
}

.aio-showcase-price {
  margin: 12px 0;
  font-size: 2rem;
  font-weight: 900;
}

.aio-key-specs {
  margin: 28px 0 0;
}

.aio-key-specs div {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding: 11px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.22);
}

.aio-key-specs dd {
  margin: 0;
  font-weight: 850;
  text-align: right;
}

.aio-feature-grid,
.aio-review-grid,
.aio-spec-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

.aio-feature-grid article,
.aio-review-grid article {
  min-height: 200px;
  padding: 24px;
  color: #fff;
  background: #03547f;
  border-radius: 8px;
}

.aio-feature-grid article > span {
  display: grid;
  width: 38px;
  height: 38px;
  margin-bottom: 22px;
  place-items: center;
  background: rgba(255, 255, 255, 0.16);
  border-radius: 50%;
}

.aio-feature-grid p,
.aio-review-grid p {
  color: rgba(255, 255, 255, 0.76);
  line-height: 1.6;
}

.aio-builder-section {
  color: #fff;
  background: #03547f;
}

.aio-builder-section .eyebrow,
.aio-builder-section .configurator-intro p {
  color: rgba(255, 255, 255, 0.78);
}

.aio-builder-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(320px, 0.7fr);
  gap: 24px;
  align-items: start;
}

.aio-controls {
  display: grid;
  gap: 4px;
}

.aio-option-set {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0;
  padding: 22px 0 26px;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.25);
}

.aio-option-set legend {
  width: 100%;
  margin-bottom: 4px;
  font-weight: 850;
}

.aio-option {
  min-height: 46px;
  padding: 11px 15px;
  color: #fff;
  background: rgba(255, 255, 255, 0.13);
  border: 2px solid transparent;
  border-radius: 8px;
  font: inherit;
  font-weight: 780;
  cursor: pointer;
}

.aio-option small {
  display: block;
  margin-top: 3px;
  color: #8bf3bd;
  font-weight: 800;
}

.aio-option.selected {
  color: #03547f;
  background: #fff;
  border-color: #fff;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.35);
}

.aio-option.selected small {
  color: #03547f;
}

.aio-option:focus-visible,
.aio-series-card:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 3px;
}

.aio-secondary-control {
  align-items: flex-start;
}

.aio-secondary-panel {
  display: flex;
  flex: 1 0 100%;
  flex-wrap: wrap;
  gap: 10px;
  padding-top: 8px;
}

.aio-live-summary {
  position: sticky;
  top: 96px;
  padding: 24px;
  background: rgba(0, 31, 49, 0.58);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 8px;
}

.aio-live-summary dl {
  margin: 20px 0;
}

.aio-live-summary dl div,
.aio-price-breakdown div {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 8px 0;
}

.aio-live-summary dt {
  color: rgba(255, 255, 255, 0.65);
}

.aio-live-summary dd {
  max-width: 58%;
  margin: 0;
  font-weight: 800;
  text-align: right;
}

.aio-price-breakdown {
  margin-top: 18px;
  padding: 18px;
  background: rgba(0, 31, 49, 0.55);
  border-radius: 8px;
}

.aio-price-breakdown > strong {
  display: block;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.22);
}

.aio-offer-row {
  margin-top: 8px;
  padding-top: 14px !important;
  border-top: 1px solid rgba(255, 255, 255, 0.22);
  font-size: 1.15rem;
}

.aio-cart-button {
  width: 100%;
  margin-top: 14px;
  color: #03547f;
  background: #fff;
}

.aio-cart-message {
  min-height: 24px;
  margin: 10px 0 0;
  color: #a7f3d0;
  font-size: 0.88rem;
  font-weight: 750;
}

.aio-spec-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.aio-spec-grid article {
  min-height: 180px;
  padding: 24px;
  background: #fff;
  border: 1px solid #d8e2e8;
  border-radius: 8px;
}

.aio-spec-grid p {
  color: var(--muted);
  line-height: 1.65;
}

.aio-review-grid article span {
  display: block;
  margin-top: 16px;
  color: #ffd75e;
}

/* Professional workstation page */
.workstation-page {
  background: #e9edf1;
}

.workstation-hero {
  display: grid;
  min-height: calc(100vh - 88px);
  place-items: center;
  padding: clamp(44px, 8vw, 110px) clamp(18px, 5vw, 72px);
  text-align: center;
  background: #f6f8fa;
}

.workstation-hero .breadcrumb {
  position: absolute;
  top: 100px;
  left: clamp(18px, 5vw, 72px);
}

.workstation-hero h1 {
  max-width: none;
  color: #4a5060;
  font-size: clamp(3rem, 6vw, 5.5rem);
}

.workstation-hero > p:not(.eyebrow) {
  max-width: 62ch;
  margin: 14px auto 0;
  color: #3d4b5d;
  font-size: 1.05rem;
  line-height: 1.65;
}

.workstation-hero .hero-actions {
  justify-content: center;
}

.workstation-series-section {
  max-width: 1800px;
}

.workstation-showcase {
  background: linear-gradient(135deg, #4e85a2, #03547f 55%, #253290);
}

.workstation-showcase > img {
  background: #d4dae1;
}

.workstation-feature-section .aio-feature-grid article {
  background: linear-gradient(145deg, #4d9ab0, #03547f);
}

.workstation-configurator-shell {
  background: linear-gradient(135deg, rgba(75, 145, 169, 0.92), #03547f 70%, #253290);
  border-radius: 8px;
}

.workstation-configurator-shell .aio-live-summary {
  position: sticky;
  top: 96px;
}

.workstation-specs-section .aio-spec-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Peripherals category page */
.peripherals-page {
  background: #f4f7f9;
}

.peripherals-hero {
  position: relative;
  display: grid;
  min-height: calc(100vh - 88px);
  overflow: hidden;
  align-items: end;
}

.peripherals-hero > img,
.peripherals-hero-overlay,
.peripherals-hero-content {
  grid-area: 1 / 1;
}

.peripherals-hero > img {
  width: 100%;
  height: 100%;
  min-height: calc(100vh - 88px);
  object-fit: cover;
}

.peripherals-hero-overlay {
  align-self: stretch;
  background: linear-gradient(90deg, rgba(0, 34, 52, 0.9) 0%, rgba(3, 84, 127, 0.68) 48%, rgba(3, 84, 127, 0.08) 80%);
}

.peripherals-hero-content {
  position: relative;
  z-index: 1;
  width: min(100%, 1280px);
  padding: clamp(42px, 8vw, 110px) clamp(18px, 6vw, 86px);
  color: #fff;
}

.peripherals-breadcrumb {
  max-width: none;
  margin: 0 0 clamp(30px, 7vh, 76px);
  color: rgba(255, 255, 255, 0.76);
}

.peripherals-hero .eyebrow {
  color: #bce8f9;
}

.peripherals-hero h1 {
  max-width: 10ch;
  font-size: clamp(3.2rem, 8vw, 7.2rem);
}

.peripherals-hero-content > p:not(.eyebrow) {
  max-width: 52ch;
  margin: 20px 0 0;
  color: rgba(255, 255, 255, 0.82);
  font-size: 1.08rem;
  line-height: 1.7;
}

.peripherals-hero .button.secondary {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.55);
}

.peripheral-family-section,
.peripheral-picks-section,
.peripheral-compare-section,
.peripheral-benefits {
  max-width: 1800px;
  margin: 0 auto;
}

.peripheral-heading-copy {
  max-width: 42ch;
  margin: 0;
  color: var(--muted);
  line-height: 1.65;
}

.peripheral-family-grid {
  display: grid;
  gap: 20px;
  max-width: 1800px;
  margin: 0 auto;
}

.peripheral-family-card {
  display: grid;
  grid-template-columns: minmax(300px, 0.9fr) minmax(0, 1.1fr);
  min-height: 360px;
  overflow: hidden;
  background: #fff;
  border: 1px solid #dbe4e9;
  border-radius: 8px;
  transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}

.peripheral-family-card:nth-child(even) {
  grid-template-columns: minmax(0, 1.1fr) minmax(300px, 0.9fr);
}

.peripheral-family-card:nth-child(even) img {
  grid-column: 2;
}

.peripheral-family-card:nth-child(even) > div {
  grid-column: 1;
  grid-row: 1;
}

.peripheral-family-card:hover,
.peripheral-family-card:focus-visible {
  border-color: #6ca9c7;
  box-shadow: 0 20px 50px rgba(3, 84, 127, 0.14);
  transform: translateY(-3px);
}

.peripheral-family-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.peripheral-family-card > div {
  position: relative;
  display: grid;
  align-content: center;
  padding: clamp(28px, 5vw, 62px);
}

.peripheral-family-card h3 {
  margin-bottom: 12px;
  color: #03547f;
  font-size: clamp(2rem, 4vw, 3.6rem);
}

.peripheral-family-card p:not(.eyebrow) {
  max-width: 56ch;
  color: var(--muted);
  line-height: 1.7;
}

.peripheral-number {
  position: absolute;
  top: 22px;
  right: 28px;
  color: #d6e6ee;
  font-size: 3rem;
  font-weight: 900;
}

.peripheral-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 20px;
  color: #03547f;
  font-weight: 850;
}

.peripheral-link b {
  font-size: 1.35rem;
  transition: transform 180ms ease;
}

.peripheral-family-card:hover .peripheral-link b {
  transform: translateX(5px);
}

.peripheral-picks-section {
  background: #fff;
}

.text-link {
  color: #03547f;
  font-weight: 850;
}

.peripheral-picks-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  max-width: 1800px;
  margin: 0 auto;
}

.peripheral-pick {
  display: grid;
  overflow: hidden;
  background: #f7fafb;
  border: 1px solid #dce5ea;
  border-radius: 8px;
}

.pick-visual {
  position: relative;
  height: 230px;
  overflow: hidden;
}

.pick-visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 240ms ease;
}

.peripheral-pick:hover .pick-visual img {
  transform: scale(1.035);
}

.pick-visual span {
  position: absolute;
  top: 14px;
  left: 14px;
  padding: 6px 9px;
  color: #fff;
  background: #03547f;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 850;
}

.peripheral-pick > div:last-child {
  display: grid;
  align-content: start;
  padding: 22px;
}

.peripheral-pick ul {
  display: grid;
  gap: 7px;
  padding-left: 20px;
  color: var(--muted);
  line-height: 1.5;
}

.pick-price {
  margin: 6px 0 18px;
  color: #03547f;
  font-size: 1.3rem;
  font-weight: 900;
}

.peripheral-pick .button {
  margin-top: auto;
}

.peripheral-compare-section {
  display: grid;
  grid-template-columns: minmax(260px, 0.65fr) minmax(0, 1.35fr);
  gap: clamp(32px, 6vw, 82px);
  background: #03547f;
  color: #fff;
}

.peripheral-compare-intro {
  align-self: center;
}

.peripheral-compare-intro .eyebrow {
  color: #bce8f9;
}

.peripheral-compare-intro p:not(.eyebrow) {
  color: rgba(255, 255, 255, 0.72);
  line-height: 1.65;
}

.peripheral-use-grid {
  display: grid;
  gap: 12px;
}

.peripheral-use-grid article {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: 4px 16px;
  padding: 20px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 8px;
}

.peripheral-use-grid h3,
.peripheral-use-grid p,
.peripheral-use-grid .use-tags {
  grid-column: 2;
}

.peripheral-use-grid p {
  margin: 4px 0 12px;
  color: rgba(255, 255, 255, 0.7);
  line-height: 1.55;
}

.use-icon {
  display: grid;
  grid-row: 1 / span 3;
  width: 42px;
  height: 42px;
  place-items: center;
  color: #03547f;
  background: #fff;
  border-radius: 50%;
}

.use-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

.use-tags span {
  padding: 5px 8px;
  background: rgba(255, 255, 255, 0.13);
  border-radius: 5px;
  font-size: 0.75rem;
  font-weight: 750;
}

.peripheral-benefits {
  display: grid;
  grid-template-columns: minmax(260px, 0.75fr) minmax(0, 1.25fr);
  gap: clamp(32px, 6vw, 82px);
}

.peripheral-benefit-list article {
  display: grid;
  grid-template-columns: 58px 1fr;
  gap: 18px;
  padding: 24px 0;
  border-bottom: 1px solid #ccdbe3;
}

.peripheral-benefit-list article:first-child {
  padding-top: 0;
}

.peripheral-benefit-list strong {
  color: #77a9c1;
  font-size: 1.5rem;
}

.peripheral-benefit-list p {
  margin-bottom: 0;
  color: var(--muted);
  line-height: 1.6;
}

/* Keyboard product page */
.keyboard-page {
  background: #e9edf1;
}

.keyboard-hero {
  position: relative;
  display: flex;
  align-items: center;
  /* Takes the photo's own 3563x1893 proportions so `cover` crops nothing.
     With a fixed height the box got relatively taller as the window
     narrowed, so cover cropped the sides and dragged the keyboard leftward
     into the copy -- which is what caused the text/image overlap. Locking
     the ratio keeps the keyboard at a constant 55.9% across, which the
     gradient below is tuned against. */
  aspect-ratio: 3563 / 1893;
  min-height: 0;
  padding: clamp(44px, 8vw, 110px) clamp(18px, 5vw, 72px);
  overflow: hidden;
  text-align: center;
}

.keyboard-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.keyboard-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Image is already cropped/composed as intended in the source file --
     no extra zoom/crop bias applied here, just centered as-is. */
  object-position: center;
}

.keyboard-hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Fades from the photo's own light backdrop tone (sampled from its left
     margin -- almost identical to body.alt-bg's own background) into
     transparency, so the copy stays legible on the left without a hard
     seam.
     Clears at 54%, just before the keyboard begins at 55.9%. It used to
     stop at 40%, which was fine only while the copy column was narrow --
     now that the column is sized responsively below, text can reach ~51%
     and needs cover that far. */
  background: linear-gradient(
    90deg,
    #e3e1e9 0%,
    rgba(227, 225, 233, 0.92) 24%,
    rgba(227, 225, 233, 0.6) 38%,
    rgba(227, 225, 233, 0.25) 47%,
    rgba(227, 225, 233, 0) 54%
  );
}

.keyboard-hero-content {
  position: relative;
  z-index: 2;
  max-width: 640px;
}

.keyboard-hero-content h1 {
  max-width: none;
  color: #4a5060;
  /* Longer heading copy -- sized down from the original clamp(3.4rem, 7vw,
     6rem) so it wraps to at least 3 words per line inside the 640px
     content column instead of one word per line. */
  font-size: clamp(2.2rem, 4.5vw, 2.75rem);
}

.keyboard-hero-content > p:not(.eyebrow) {
  max-width: 58ch;
  margin: 14px auto 0;
  color: #3d4b5d;
  font-size: 1.05rem;
  line-height: 1.65;
}

.keyboard-hero .hero-actions {
  justify-content: center;
}

.keyboard-picker-section,
.keyboard-detail-section,
.keyboard-feature-section,
.keyboard-reviews,
.keyboard-cta {
  max-width: 1800px;
  margin: 0 auto;
}

.keyboard-card-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}

.keyboard-product-card {
  position: relative;
  display: grid;
  min-height: 450px;
  padding: 40px 36px;
  color: #fff;
  text-align: center;
  background: linear-gradient(145deg, #6b7480, #3c4856);
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  transition: box-shadow 180ms ease, transform 180ms ease, background 180ms ease;
}

.keyboard-product-card.selected {
  background: linear-gradient(145deg, #2cabc6, #03547f 72%, #163f88);
  box-shadow: 0 18px 45px rgba(3, 84, 127, 0.24);
}

.keyboard-product-card:hover,
.keyboard-product-card:focus-visible {
  transform: translateY(-4px);
  outline: 3px solid rgba(3, 84, 127, 0.22);
  outline-offset: 3px;
}

.keyboard-product-card img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  margin-bottom: 22px;
  background: #d3d9df;
  border-radius: 8px;
}

.keyboard-product-card h3 {
  margin: 0;
  font-size: 1.13rem;
}

.keyboard-product-card strong {
  display: block;
  margin: 12px 0 14px;
  font-size: 1.45rem;
}

.keyboard-product-card p {
  max-width: 34ch;
  margin: 0 auto;
  color: rgba(255, 255, 255, 0.8);
  font-weight: 700;
  line-height: 1.55;
}

.selected-dot {
  position: absolute;
  top: 24px;
  right: 24px;
  display: grid;
  width: 22px;
  height: 22px;
  place-items: center;
  background: rgba(255, 255, 255, 0.16);
  border-radius: 50%;
}

.keyboard-product-card.selected .selected-dot::before {
  content: "";
  width: 9px;
  height: 9px;
  background: #fff;
  border-radius: 50%;
}

.keyboard-detail-card {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(320px, 1.05fr);
  gap: clamp(28px, 5vw, 62px);
  padding: clamp(28px, 5vw, 58px);
  color: #fff;
  background: linear-gradient(135deg, #6b7cab, #03547f 74%, #253290);
  border-radius: 8px;
}

.keyboard-detail-copy {
  display: grid;
  align-content: start;
}

.keyboard-detail-copy .eyebrow {
  color: #d8f1fb;
}

.keyboard-detail-copy h2 {
  color: #fff;
}

.keyboard-price {
  margin: 0 0 14px;
  font-size: 1.8rem;
  font-weight: 900;
}

.keyboard-detail-copy > p:not(.eyebrow):not(.keyboard-price) {
  color: rgba(255, 255, 255, 0.84);
  line-height: 1.65;
}

.keyboard-detail-copy h3 {
  margin: 34px 0 14px;
}

.keyboard-detail-card .button.secondary {
  color: #fff;
  background: transparent;
  border-color: rgba(255, 255, 255, 0.78);
}

.keyboard-detail-visual {
  display: grid;
  min-height: 500px;
  overflow: hidden;
  align-self: stretch;
  background: #d4dae1;
  border-radius: 8px;
}

.keyboard-detail-visual img,
.keyboard-detail-visual video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.keyboard-spec-list {
  display: grid;
  gap: 0;
  margin: 0;
}

.keyboard-spec-list div {
  display: grid;
  grid-template-columns: minmax(130px, 0.5fr) minmax(0, 1fr);
  gap: 16px;
  padding: 12px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.22);
}

.keyboard-spec-list dt {
  color: rgba(255, 255, 255, 0.72);
  font-weight: 750;
}

.keyboard-spec-list dd {
  margin: 0;
  color: #fff;
  font-weight: 850;
  text-align: right;
  overflow-wrap: anywhere;
}

.keyboard-feature-grid,
.keyboard-review-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}

.keyboard-feature-grid article,
.keyboard-review-grid article {
  padding: 38px;
  color: #fff;
  background: linear-gradient(145deg, #4d9ab0, #03547f 70%, #16408c);
  border-radius: 8px;
}

.keyboard-feature-grid span {
  display: grid;
  width: 44px;
  height: 44px;
  margin-bottom: 28px;
  place-items: center;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 50%;
  font-size: 0.78rem;
  font-weight: 900;
}

.keyboard-feature-grid h3,
.keyboard-review-grid h3 {
  color: #fff;
}

.keyboard-feature-grid p,
.keyboard-review-grid blockquote {
  margin: 14px 0 0;
  color: rgba(255, 255, 255, 0.82);
  font-weight: 700;
  line-height: 1.65;
}

.keyboard-review-grid article {
  background: linear-gradient(145deg, #2e9ab2, #03547f);
}

.keyboard-review-grid article > div {
  display: grid;
  grid-template-columns: 42px 1fr;
  gap: 0 14px;
  align-items: center;
}

.keyboard-review-grid span {
  display: grid;
  grid-row: 1 / span 2;
  width: 38px;
  height: 38px;
  place-items: center;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 50%;
  font-weight: 900;
}

.keyboard-review-grid small {
  color: rgba(255, 255, 255, 0.7);
  font-weight: 750;
}

.stars {
  margin: 22px 0 0;
  color: #ffd642;
  letter-spacing: 0;
  font-weight: 900;
}

.keyboard-review-grid blockquote {
  font-style: italic;
}

.keyboard-cta {
  background: linear-gradient(135deg, #4e85a2, #03547f 55%, #253290);
}

/* Centered/stacked instead of the shared .cta-band class's left-text/
   right-button row -- same treatment as #desktop-cta, with the button
   sitting directly under the last line of text. */
.keyboard-cta {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

.keyboard-cta > div:not(.hero-actions) {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.keyboard-cta h2 {
  max-width: 960px;
  margin: 0 auto;
}

.keyboard-cta .hero-actions {
  /* .cta-band's own flex `gap: 24px` already spaces this from the text
     block above now that the section is a column layout -- dropping the
     default .hero-actions top margin keeps the button snug under the
     last line instead of doubling up the spacing. */
  margin-top: 0;
}

/* (The centering for this band lives with the other .cta-band variants --
   see `.cta-band.keyboard-cta` further down. A `@media (max-width: 720px)
   .keyboard-cta` rule used to sit here, but it was earlier in the file than
   the `.cta-band { align-items: flex-start }` it needed to beat, so it
   never took effect.) */

/* Monitor product page */
.monitor-page {
  background: #e9edf1;
}

.monitor-hero {
  position: relative;
  display: grid;
  min-height: calc(100vh - 88px);
  place-items: center;
  padding: clamp(44px, 8vw, 110px) clamp(18px, 5vw, 72px);
  overflow: hidden;
  text-align: center;
}

/* The video variant is a short decorative banner (logo animation, no
   overlaid heading text) rather than a full-viewport hero -- shorter and
   fixed-ish height, similar in proportion to a typical brand-video banner
   (e.g. Dell's solutions page video strip) instead of filling the screen. */
.monitor-hero-video {
  min-height: 0;
  /* +20% on all three clamp values (was 380px / 65vh / 720px). */
  height: clamp(456px, 78vh, 864px);
}

.monitor-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.monitor-hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.monitor-hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(233, 237, 241, 0.82);
}

.monitor-hero-video {
  padding: 0;
}

.monitor-hero-video-el {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* ===========================================================================
   Monitor hero video -- fit the whole frame on small screens
   ---------------------------------------------------------------------------
   The clip is 1920x818: a 2.35:1 cinematic strip. (The source arrived as a
   16:9 file with the strip letterboxed inside it -- 133px of black on top,
   129px underneath. Those bars were cropped off in the encode rather than
   left in, because `cover` on the desktop box only trims about 45px per
   side, so most of each bar would have stayed visible as a black band across
   an otherwise light page.) The section's height is
   set in vh, so as the window narrows the box gets *taller* relative to its
   width while the clip's shape doesn't change -- `cover` then scales to
   height and throws the sides away. On a 390x844 phone that box is about
   0.6:1 against the clip's 2.6:1, which is roughly three quarters of the
   frame gone; all that's left is the middle of the monitor stand.

   Below 900px the vh height gives way to the clip's own ratio, so the whole
   frame fits with nothing cropped. `contain` alongside it is belt and
   braces: against a matching ratio it behaves exactly like `cover`, but if
   the clip is ever re-encoded at different dimensions it will letterbox
   into the dark backdrop rather than quietly start cropping again.

   The trade is height -- a 2.6:1 banner is only ~150px tall on a 390px
   screen. That's inherent to fitting a cinematic strip onto a portrait
   phone: the whole frame or a tall section, not both. */
@media (max-width: 900px) {
  .monitor-hero-video {
    height: auto;
    aspect-ratio: 1920 / 818;
    background: #0b0d10;
  }

  .monitor-hero-video-el {
    object-fit: contain;
  }
}

.monitor-hero-mute-toggle {
  position: absolute;
  right: 24px;
  bottom: 24px;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: rgba(20, 24, 26, 0.55);
  color: #fff;
  cursor: pointer;
  transition: background 0.2s ease;
}

.monitor-hero-mute-toggle:hover {
  background: rgba(20, 24, 26, 0.75);
}

.monitor-hero-mute-toggle .icon-unmuted {
  display: none;
}

.monitor-hero-mute-toggle[aria-pressed="true"] .icon-muted {
  display: none;
}

.monitor-hero-mute-toggle[aria-pressed="true"] .icon-unmuted {
  display: block;
}

.monitor-hero > .eyebrow,
.monitor-hero > h1,
.monitor-hero > p:not(.eyebrow),
.monitor-hero > .hero-actions {
  position: relative;
  z-index: 2;
}

.monitor-hero .breadcrumb {
  position: absolute;
  top: 100px;
  left: clamp(18px, 5vw, 72px);
  z-index: 2;
}

.monitor-hero h1 {
  max-width: none;
  color: #4a5060;
  font-size: clamp(3.6rem, 7vw, 6.2rem);
}

.monitor-hero > p:not(.eyebrow) {
  max-width: 58ch;
  margin: 14px auto 0;
  color: #3d4b5d;
  font-size: 1.05rem;
  line-height: 1.65;
}

.monitor-hero .hero-actions {
  justify-content: center;
}

.monitor-picker-section,
.monitor-detail-section,
.monitor-feature-section,
.monitor-spec-overview,
.monitor-why-section,
.monitor-reviews,
.monitor-cta {
  max-width: 1800px;
  margin: 0 auto;
}

/* Match the section-heading rows to the same widened cap above so the
   eyebrow/heading line up with the edges of the wider card grids below
   them, instead of sitting narrower and inboard (same fix applied on
   the Desktop PCs page). */
.monitor-picker-section .section-heading,
.monitor-feature-section .section-heading,
.monitor-reviews .section-heading {
  max-width: none;
}

.monitor-spec-overview > h2,
.monitor-why-section > h2,
.mouse-spec-overview > h2,
.mouse-why-section > h2 {
  margin-bottom: 28px;
}

.monitor-card-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
}

.monitor-product-card {
  position: relative;
  display: grid;
  align-content: start;
  min-height: 430px;
  padding: 34px 28px;
  color: #fff;
  text-align: center;
  background: linear-gradient(145deg, #6b7480, #3c4856);
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  transition: box-shadow 180ms ease, transform 180ms ease, background 180ms ease;
  /* Clips the scroll-zoom image's zoomed-in state to the card -- see
     scroll-zoom.js. Doesn't affect layout/spacing. */
  overflow: hidden;
}

.monitor-product-card.selected {
  background: linear-gradient(145deg, #2cabc6, #03547f 72%, #163f88);
  box-shadow: 0 18px 45px rgba(3, 84, 127, 0.24);
}

.monitor-product-card:hover,
.monitor-product-card:focus-visible {
  transform: translateY(-4px);
  outline: 3px solid rgba(3, 84, 127, 0.22);
  outline-offset: 3px;
}

.monitor-product-card img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  margin-bottom: 18px;
  background: #d3d9df;
  border-radius: 8px;
}

.monitor-product-card h3 {
  margin: 0;
  font-size: 1.03rem;
  line-height: 1.35;
}

.monitor-product-card small {
  display: block;
  margin: 10px 0;
  color: rgba(255, 255, 255, 0.72);
  font-weight: 800;
}

.monitor-product-card strong {
  display: block;
  margin: 0 0 14px;
  font-size: 1.45rem;
}

.monitor-product-card p {
  max-width: 32ch;
  margin: 0 auto;
  color: rgba(255, 255, 255, 0.8);
  font-weight: 700;
  line-height: 1.5;
}

.monitor-detail-card {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(320px, 1.05fr);
  gap: clamp(28px, 5vw, 62px);
  padding: clamp(28px, 5vw, 58px);
  color: #fff;
  background: linear-gradient(145deg, #305448, #03547f);
  border-radius: 8px;
}

.monitor-detail-copy {
  display: grid;
  align-content: start;
}

.monitor-detail-copy .eyebrow {
  color: #d8f1fb;
}

.monitor-detail-copy h2 {
  color: #fff;
}

.monitor-price {
  margin: 0 0 14px;
  font-size: 1.8rem;
  font-weight: 900;
}

.monitor-detail-copy > p:not(.eyebrow):not(.monitor-price) {
  color: rgba(255, 255, 255, 0.84);
  line-height: 1.65;
}

.monitor-detail-copy h3 {
  margin: 34px 0 14px;
}

.monitor-detail-card .button.secondary,
.monitor-cta .button.secondary {
  color: #fff;
  background: transparent;
  border-color: rgba(255, 255, 255, 0.78);
}

.monitor-detail-visual {
  display: grid;
  min-height: 560px;
  overflow: hidden;
  align-self: stretch;
  background: #d4dae1;
  border-radius: 8px;
}

.monitor-detail-visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.monitor-spec-list,
.monitor-overview-card dl {
  display: grid;
  gap: 0;
  margin: 0;
}

.monitor-spec-list div,
.monitor-overview-card dl div {
  display: grid;
  grid-template-columns: minmax(130px, 0.5fr) minmax(0, 1fr);
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.22);
}

.monitor-spec-list dt,
.monitor-overview-card dt {
  color: rgba(255, 255, 255, 0.72);
  font-weight: 750;
}

.monitor-spec-list dd,
.monitor-overview-card dd {
  margin: 0;
  color: #fff;
  font-weight: 850;
  text-align: right;
  overflow-wrap: anywhere;
}

.monitor-feature-grid,
.monitor-review-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}

.monitor-feature-grid article,
.monitor-review-grid article {
  padding: 38px;
  color: #fff;
  background: linear-gradient(145deg, #4d9ab0, #03547f 70%, #16408c);
  border-radius: 8px;
}

.monitor-feature-grid span {
  display: grid;
  width: 46px;
  height: 46px;
  margin-bottom: 28px;
  place-items: center;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 50%;
  font-size: 0.74rem;
  font-weight: 900;
}

.monitor-feature-grid h3,
.monitor-review-grid h3,
.monitor-overview-card h3,
.monitor-why-grid h3 {
  color: #fff;
}

.monitor-feature-grid p,
.monitor-review-grid blockquote {
  margin: 14px 0 0;
  color: rgba(255, 255, 255, 0.82);
  font-weight: 700;
  line-height: 1.65;
}

.monitor-overview-card {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 28px 48px;
  padding: clamp(28px, 5vw, 48px);
  color: #fff;
  background: linear-gradient(145deg, #4d9ab0, #03547f 70%, #16408c);
  border-radius: 8px;
}

.monitor-table-wrap {
  grid-column: 1 / -1;
  overflow-x: auto;
}

.monitor-table-wrap table {
  width: 100%;
  min-width: 680px;
  border-collapse: collapse;
  color: #fff;
}

.monitor-table-wrap th,
.monitor-table-wrap td {
  padding: 12px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  text-align: left;
}

.monitor-table-wrap th {
  color: rgba(255, 255, 255, 0.78);
  font-size: 0.82rem;
}

.monitor-why-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
}

.monitor-why-grid article {
  padding: 38px;
  color: #fff;
  background: linear-gradient(145deg, #305448, #03547f);
  border-radius: 8px;
}

.monitor-why-grid ul {
  display: grid;
  gap: 10px;
  padding-left: 18px;
  color: rgba(255, 255, 255, 0.86);
  font-weight: 750;
}

.monitor-review-grid article {
  background: linear-gradient(145deg, #2e9ab2, #03547f);
}

.monitor-review-grid article > div {
  display: grid;
  grid-template-columns: 42px 1fr;
  gap: 0 14px;
  align-items: center;
}

.monitor-review-grid span {
  display: grid;
  grid-row: 1 / span 2;
  width: 38px;
  height: 38px;
  place-items: center;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 50%;
  font-weight: 900;
}

.monitor-review-grid small {
  color: rgba(255, 255, 255, 0.7);
  font-weight: 750;
}

.monitor-review-grid blockquote {
  font-style: italic;
}

.monitor-cta {
  background: linear-gradient(135deg, #4e85a2, #03547f 55%, #253290);
}

/* Centered/stacked instead of the shared .cta-band class's left-text/
   right-button row -- scoped to .monitor-cta only (same treatment as
   #desktop-cta on the Desktop PCs page). */
.monitor-cta {
  flex-direction: column;
  justify-content: center;
  gap: 8px;
  text-align: center;
}

.monitor-cta > div:first-child {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.monitor-cta h3 {
  margin: 0 auto;
  font-size: 1.7rem;
}

.monitor-cta .eyebrow {
  font-size: 1.05rem;
}

.monitor-cta p:not(.eyebrow) {
  font-size: 1.25rem;
}

/* (Centering lives with the other .cta-band variants -- see
   `.cta-band.monitor-cta` further down. The dead `@media (max-width: 720px)`
   rule that used to sit here is described above the keyboard one.) */

/* Mouse product page */
.mouse-page {
  background: #e9edf1;
}

.mouse-hero {
  position: relative;
  display: flex;
  align-items: center;
  /* Takes the video's own 16:9 proportions so `cover` crops nothing --
     the mouse and its glow ring stay put at ~48% across, which the
     gradient below is tuned against. A fixed viewport height cropped the
     sides as the window narrowed, dragging the product into the copy.
     Also removes the full-screen hero: the page now starts paying off
     before the visitor has to scroll. */
  aspect-ratio: 16 / 9;
  min-height: 0;
  padding: clamp(44px, 8vw, 110px) clamp(18px, 5vw, 72px);
  overflow: hidden;
  text-align: center;
}

.mouse-hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.mouse-hero-media img,
.mouse-hero-media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The mouse itself and the small size-variant thumbnails sit toward the
     right of the source photo/video -- anchoring the crop there keeps them
     in frame as the section narrows, while the empty left backdrop (where
     the hero copy sits) crops away first. */
  object-position: right center;
}

.mouse-hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Fades from the video's own backdrop tone (sampled from its left margin
     across several frames, since the shot has a subtle lighting shift over
     its 8s loop) into transparency, so the copy stays legible on the left
     without a hard seam where the product shot begins. */
  /* Clears at 48%, where the mouse's glow ring begins, so the product is
     never veiled. Previously ran to 78%, which washed over the whole
     product now that the frame is no longer cropped. */
  background: linear-gradient(
    90deg,
    #a9a7b4 0%,
    rgba(169, 167, 180, 0.9) 24%,
    rgba(169, 167, 180, 0.55) 36%,
    rgba(169, 167, 180, 0.2) 43%,
    rgba(169, 167, 180, 0) 48%
  );
}

.mouse-hero-content {
  position: relative;
  z-index: 2;
  max-width: 640px;
}

.mouse-hero-content h1 {
  max-width: none;
  color: #4a5060;
  /* Longer heading copy -- sized down from the original clamp(3.6rem, 7vw,
     6.2rem) so it wraps to at least 3 words per line inside the 640px
     content column instead of one word per line (same treatment as the
     keyboard page hero). */
  font-size: clamp(2.2rem, 4.5vw, 2.75rem);
}

.mouse-hero-content > p:not(.eyebrow) {
  max-width: 58ch;
  margin: 14px auto 0;
  color: #3d4b5d;
  font-size: 1.05rem;
  line-height: 1.65;
}

.mouse-hero .hero-actions {
  justify-content: center;
}

.mouse-picker-section,
.mouse-detail-section,
.mouse-feature-section,
.mouse-spec-overview,
.mouse-why-section,
.mouse-reviews,
.mouse-cta {
  max-width: 1800px;
  margin: 0 auto;
}

.mouse-card-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
}

.mouse-product-card {
  position: relative;
  display: grid;
  align-content: start;
  min-height: 420px;
  padding: 34px 28px;
  color: #fff;
  text-align: center;
  background: linear-gradient(145deg, #6b7480, #3c4856);
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  transition: box-shadow 180ms ease, transform 180ms ease, background 180ms ease;
}

.mouse-product-card.selected {
  background: linear-gradient(145deg, #2cabc6, #03547f 72%, #163f88);
  box-shadow: 0 18px 45px rgba(3, 84, 127, 0.24);
}

.mouse-product-card:hover,
.mouse-product-card:focus-visible {
  transform: translateY(-4px);
  outline: 3px solid rgba(3, 84, 127, 0.22);
  outline-offset: 3px;
}

.mouse-product-card img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  margin-bottom: 18px;
  background: #d3d9df;
  border-radius: 8px;
}

.mouse-product-card h3 {
  margin: 0;
  font-size: 1.03rem;
  line-height: 1.35;
}

.mouse-product-card small {
  display: block;
  margin: 10px 0;
  color: rgba(255, 255, 255, 0.72);
  font-weight: 800;
}

.mouse-product-card strong {
  display: block;
  margin: 0 0 14px;
  font-size: 1.45rem;
}

.mouse-product-card p {
  max-width: 32ch;
  margin: 0 auto;
  color: rgba(255, 255, 255, 0.8);
  font-weight: 700;
  line-height: 1.5;
}

.mouse-detail-card {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(320px, 1.05fr);
  gap: clamp(28px, 5vw, 62px);
  padding: clamp(28px, 5vw, 58px);
  color: #fff;
  background: linear-gradient(135deg, #6b7cab, #03547f 74%, #253290);
  border-radius: 8px;
}

.mouse-detail-copy {
  display: grid;
  align-content: start;
}

.mouse-detail-copy .eyebrow {
  color: #d8f1fb;
}

.mouse-detail-copy h2 {
  color: #fff;
}

.mouse-price {
  margin: 0 0 14px;
  font-size: 1.8rem;
  font-weight: 900;
}

.mouse-detail-copy > p:not(.eyebrow):not(.mouse-price) {
  color: rgba(255, 255, 255, 0.84);
  line-height: 1.65;
}

.mouse-detail-copy h3 {
  margin: 34px 0 14px;
}

.mouse-detail-card .button.secondary,
.mouse-cta .button.secondary {
  color: #fff;
  background: transparent;
  border-color: rgba(255, 255, 255, 0.78);
}

.mouse-detail-visual {
  display: grid;
  min-height: 520px;
  overflow: hidden;
  align-self: stretch;
  background: #d4dae1;
  border-radius: 8px;
}

.mouse-detail-visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mouse-spec-list,
.mouse-overview-card dl {
  display: grid;
  gap: 0;
  margin: 0;
}

.mouse-spec-list div,
.mouse-overview-card dl div {
  display: grid;
  grid-template-columns: minmax(130px, 0.5fr) minmax(0, 1fr);
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.22);
}

.mouse-spec-list dt,
.mouse-overview-card dt {
  color: rgba(255, 255, 255, 0.72);
  font-weight: 750;
}

.mouse-spec-list dd,
.mouse-overview-card dd {
  margin: 0;
  color: #fff;
  font-weight: 850;
  text-align: right;
  overflow-wrap: anywhere;
}

.mouse-feature-grid,
.mouse-review-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}

.mouse-feature-grid article,
.mouse-review-grid article {
  padding: 38px;
  color: #fff;
  background: linear-gradient(145deg, #4d9ab0, #03547f 70%, #16408c);
  border-radius: 8px;
}

.mouse-feature-grid span {
  display: grid;
  width: 46px;
  height: 46px;
  margin-bottom: 28px;
  place-items: center;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 50%;
  font-size: 0.7rem;
  font-weight: 900;
}

.mouse-feature-grid h3,
.mouse-review-grid h3,
.mouse-overview-card h3,
.mouse-why-grid h3 {
  color: #fff;
}

.mouse-feature-grid p,
.mouse-review-grid blockquote {
  margin: 14px 0 0;
  color: rgba(255, 255, 255, 0.82);
  font-weight: 700;
  line-height: 1.65;
}

.mouse-overview-card {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 28px 48px;
  padding: clamp(28px, 5vw, 48px);
  color: #fff;
  background: linear-gradient(145deg, #66717d, #263548);
  border-radius: 8px;
}

.mouse-table-wrap {
  grid-column: 1 / -1;
  overflow-x: auto;
}

.mouse-table-wrap table {
  width: 100%;
  min-width: 680px;
  border-collapse: collapse;
  color: #fff;
}

.mouse-table-wrap th,
.mouse-table-wrap td {
  padding: 12px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  text-align: left;
}

.mouse-table-wrap th {
  color: rgba(255, 255, 255, 0.78);
  font-size: 0.82rem;
}

.mouse-why-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
}

.mouse-why-grid article {
  padding: 38px;
  color: #fff;
  background: linear-gradient(145deg, #305448, #03547f);
  border-radius: 8px;
}

.mouse-why-grid ul {
  display: grid;
  gap: 10px;
  padding-left: 18px;
  color: rgba(255, 255, 255, 0.86);
  font-weight: 750;
}

.mouse-review-grid article {
  background: linear-gradient(145deg, #2e9ab2, #03547f);
}

.mouse-review-grid article > div {
  display: grid;
  grid-template-columns: 42px 1fr;
  gap: 0 14px;
  align-items: center;
}

.mouse-review-grid span {
  display: grid;
  grid-row: 1 / span 2;
  width: 38px;
  height: 38px;
  place-items: center;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 50%;
  font-weight: 900;
}

.mouse-review-grid small {
  color: rgba(255, 255, 255, 0.7);
  font-weight: 750;
}

.mouse-review-grid blockquote {
  font-style: italic;
}

.mouse-cta {
  background: linear-gradient(135deg, #4e85a2, #03547f 55%, #253290);
}

/* Centered/stacked instead of the shared .cta-band class's left-text/
   right-button row -- same treatment as #desktop-cta and .keyboard-cta,
   with the button sitting directly under the last line of text. */
.mouse-cta {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

.mouse-cta > div:not(.hero-actions) {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.mouse-cta h2 {
  max-width: 960px;
  margin: 0 auto;
}

.mouse-cta .hero-actions {
  margin-top: 0;
}

/* (Centering lives with the other .cta-band variants -- see
   `.cta-band.mouse-cta` further down.) */

/* Contact page -- a white card floating on the page background, split
   into the message form on the left and a dark "always here to help"
   panel on the right (icon rows for each contact channel, then social
   links), rather than a plain two-column list-and-form layout. */
.contact-section {
  background: transparent;
}

/* Simple one-column contact block reused on Support and Dealer pages
   (phone/email/address list + WhatsApp button, no form) -- kept alongside
   the richer contact-card layout below, which is specific to the main
   Contact page. */
.contact-grid {
  display: grid;
  grid-template-columns: minmax(260px, 0.85fr) minmax(320px, 1.15fr);
  gap: clamp(28px, 5vw, 64px);
  max-width: 1800px;
  margin: 0 auto;
}

.contact-info h2 {
  margin: 8px 0 14px;
}

.contact-info > p:not(.eyebrow) {
  color: var(--muted);
  line-height: 1.65;
}

/* Support page -- the h2 was removed and the eyebrow now serves as the
   section's de facto heading, so it needs to read at heading size instead
   of small-label size. Scoped to #support-contact-info only: .contact-info
   .eyebrow is shared with the dealer page, which still has its own h2 and
   should keep the small eyebrow treatment. */
#support-contact-info.contact-info .eyebrow {
  margin: 0 0 14px;
  font-size: 2rem;
  font-weight: 800;
  letter-spacing: 0;
  text-transform: none;
}

.contact-detail-list {
  display: grid;
  gap: 16px;
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
}

.contact-detail-list li {
  display: grid;
  gap: 10px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
}

.contact-detail-list li:last-child {
  border-bottom: 0;
}

.contact-detail-label {
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.contact-detail-list a {
  color: var(--accent-dark);
  font-weight: 750;
}

.whatsapp-button {
  margin-top: 24px;
  color: #fff;
  background: #25d366;
  box-shadow: 0 12px 24px rgba(37, 211, 102, 0.28);
}

.contact-card {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(280px, 1fr);
  align-items: center;
  gap: 0;
  max-width: 1800px;
  margin: 0 auto;
  background: #ffffff;
  border-radius: 20px;
  box-shadow: var(--shadow);
}

.contact-form-panel {
  padding: clamp(28px, 4vw, 44px);
}

.contact-form-panel h2 {
  margin: 8px 0 10px;
}

.contact-form-intro {
  max-width: 46ch;
  color: var(--muted);
  line-height: 1.6;
  font-size: 0.94rem;
}

.contact-form {
  display: grid;
  align-content: start;
}

.contact-form-submit-row {
  display: flex;
  justify-content: flex-end;
  margin-top: 24px;
}

.contact-form-submit-row .button {
  min-width: 200px;
}

/* Dark help panel -- sits inset inside the white card (its own rounded
   box with margin on every side) rather than stretching edge-to-edge, and
   sized to its content instead of matching the form column's full
   height. */
.contact-help-panel {
  display: flex;
  flex-direction: column;
  align-self: center;
  margin: clamp(18px, 3vw, 28px);
  padding: clamp(20px, 3vw, 28px) clamp(18px, 3vw, 24px);
  color: #fff;
  background: var(--accent-dark);
  border-radius: 16px;
}

.contact-help-heading {
  max-width: 22ch;
  margin: 0 0 22px;
  font-size: 1.3rem;
  font-weight: 800;
  line-height: 1.35;
}

.contact-help-list {
  display: grid;
  gap: 12px;
}

.contact-help-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  color: #fff;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 12px;
  font-size: 0.88rem;
  line-height: 1.5;
  transition: background 160ms ease;
}

a.contact-help-item:hover {
  background: rgba(255, 255, 255, 0.18);
}

.contact-help-item-static {
  cursor: default;
}

.contact-help-icon {
  display: grid;
  flex: 0 0 auto;
  place-items: center;
  width: 38px;
  height: 38px;
  color: #fff;
  background: rgba(255, 255, 255, 0.14);
  border-radius: 50%;
}

.contact-help-icon svg {
  width: 18px;
  height: 18px;
}

.contact-help-divider {
  margin: 26px 0 18px;
  border: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.2);
}

.contact-help-connect {
  margin: 0 0 14px;
  font-weight: 750;
}

.contact-help-social {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.contact-help-social a {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  color: #fff;
  background: rgba(255, 255, 255, 0.14);
  border-radius: 50%;
}

.contact-help-social a:hover {
  background: rgba(255, 255, 255, 0.26);
}

.contact-help-social svg {
  width: 17px;
  height: 17px;
}

.form-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.form-field {
  display: grid;
  gap: 6px;
  margin-top: 16px;
}

.contact-form > .form-field:first-of-type,
.contact-form > .form-row {
  margin-top: 18px;
}

.form-field label {
  color: var(--ink);
  font-weight: 750;
  font-size: 0.92rem;
}

.form-field input,
.form-field select,
.form-field textarea {
  width: 100%;
  padding: 11px 14px;
  color: var(--ink);
  background: #ffffff;
  border: 1px solid var(--line);
  border-radius: 8px;
  font: inherit;
  font-size: 0.96rem;
}

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: 3px solid rgba(3, 84, 127, 0.22);
  outline-offset: 1px;
  border-color: var(--accent);
}

.form-field textarea {
  resize: vertical;
}

.form-hint {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 0.82rem;
}

.form-optional {
  color: var(--muted);
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
}

.form-checkbox-field label {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  color: var(--muted);
  font-weight: 600;
  font-size: 0.9rem;
  line-height: 1.5;
  cursor: pointer;
}

.form-checkbox-field input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  flex: 0 0 auto;
  accent-color: var(--accent);
}

.contact-form button[type="submit"] {
  width: 100%;
  margin-top: 22px;
}

.form-status {
  min-height: 22px;
  margin: 12px 0 0;
  font-weight: 750;
  font-size: 0.9rem;
}

.form-status.is-success {
  color: #1a8f5e;
}

.form-status.is-error {
  color: #c23b3b;
}

/* "Enter your details" gate shown before a Download Quotation PDF --
   injected once into <body> by configurator-engine.js, reused across every
   download click for the rest of the browser session. */
.lead-gate-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(20, 32, 29, 0.56);
}

.lead-gate-overlay.is-hidden {
  display: none;
}

.lead-gate-modal {
  position: relative;
  width: 100%;
  max-width: 420px;
  padding: clamp(24px, 5vw, 34px);
  color: var(--ink);
  background: #ffffff;
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.lead-gate-modal h3 {
  margin: 6px 0 10px;
}

.lead-gate-copy {
  margin: 0 0 20px;
  color: var(--muted);
  line-height: 1.55;
}

.lead-gate-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 30px;
  height: 30px;
  color: var(--muted);
  background: transparent;
  border: 0;
  border-radius: 6px;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

.lead-gate-close:hover {
  background: var(--paper);
}

.lead-gate-modal .button.primary {
  width: 100%;
  margin-top: 20px;
  border: 0;
  cursor: pointer;
}

@media (max-width: 980px) {
  .hero,
  .split-band,
  .category-layout,
  .spec-band {
    grid-template-columns: 1fr;
  }

  h1 {
    max-width: 13ch;
  }

  .product-grid,
  .model-grid,
  .pricing-grid,
  .feature-list,
  .spec-grid,
  .option-grid.three-col,
  .peripheral-grid,
  .summary-panel {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .option-grid.two-col,
  .summary-panel {
    grid-template-columns: 1fr;
  }

  .quote-panel {
    padding-left: 0;
    border-left: 0;
    border-top: 2px solid rgba(255, 255, 255, 0.42);
    padding-top: 20px;
  }

  .aio-hero,
  .aio-showcase,
  .aio-builder-grid {
    grid-template-columns: 1fr;
  }

  .aio-live-summary,
  .workstation-configurator-shell .aio-live-summary {
    position: static;
  }

  .peripheral-picks-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .peripheral-compare-section,
  .peripheral-benefits,
  .keyboard-detail-card,
  .monitor-detail-card,
  .monitor-overview-card,
  .mouse-detail-card,
  .mouse-overview-card {
    grid-template-columns: 1fr;
  }

  .keyboard-card-grid,
  .keyboard-feature-grid,
  .keyboard-review-grid,
  .monitor-card-grid,
  .monitor-feature-grid,
  .monitor-review-grid,
  .monitor-why-grid,
  .mouse-card-grid,
  .mouse-feature-grid,
  .mouse-review-grid,
  .mouse-why-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .keyboard-detail-visual,
  .monitor-detail-visual,
  .mouse-detail-visual {
    min-height: 360px;
  }

  .monitor-table-wrap,
  .mouse-table-wrap {
    grid-column: 1;
  }
}

@media (max-width: 720px) {
  .cta-band,
  .section-heading {
    align-items: flex-start;
    flex-direction: column;
  }

  /* Once the heading stacks it's a full-width block on its own rather than
     the left half of an eyebrow/heading row, and left-aligned it read as
     drifted off to one side -- same reasoning as the .split-band heading
     column. The .cta-band above keeps flex-start: its copy sits beside a
     button and reads as a row, not a title block. */
  .section-heading {
    align-items: center;
    text-align: center;
  }

  /* -------------------------------------------------------------------
     Mobile navigation.
     Header stays a single row (brand left, hamburger right); the nav
     itself becomes a panel that drops below it. The panel is closed by
     default and revealed by .nav-open, which mobile-nav.js toggles.
     ------------------------------------------------------------------- */
  .site-header {
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
  }

  .nav-toggle {
    display: inline-flex;
  }

  .site-nav {
    /* display:none rather than height:0 so the links are genuinely
       untabbable while the panel is shut. */
    display: none;
    order: 3;
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-top: 4px;
    padding-bottom: 8px;
  }

  .site-header.nav-open .site-nav {
    display: flex;
  }

  .site-nav > a,
  .nav-products-trigger {
    padding: 14px 2px;
    border-bottom: 1px solid var(--line);
  }

  /* The chevron points down when collapsed and flips when expanded --
     the desktop :hover rule that normally does this can't fire here. */
  .nav-products.is-expanded .nav-chevron {
    transform: translateY(2px) rotate(225deg);
  }

  /* Products sub-list: part of the document flow inside the panel, not a
     floating overlay. Collapsed until mobile-nav.js adds .is-expanded on
     the first tap. */
  .products-menu {
    position: static;
    display: none;
    width: auto;
    max-width: none;
    padding: 6px 0 14px 10px;
    background: none;
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    box-shadow: none;
    /* Reset the desktop show/hide mechanism entirely -- visibility and
       opacity are handled by display here, and leaving the transform in
       place would offset the sub-list. */
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: none;
    pointer-events: auto;
  }

  .nav-products.is-expanded .products-menu {
    display: block;
  }

  /* The desktop open-state rule (.nav-products:hover .products-menu) sets
     `transform: translate(-50%, 0)` and outranks the plain .products-menu
     rule above on specificity. A tap on a touchscreen leaves a sticky
     :hover behind, so that rule was still winning here and shifting the
     whole sub-list left by half its own width -- straight off the screen
     edge, which is why the rows looked blank.
     These selectors match its specificity and come later, so they win.
     Position is static at this breakpoint, so top/left are inert too. */
  .nav-products:hover .products-menu,
  .nav-products:focus-within .products-menu,
  .nav-products.is-expanded .products-menu {
    transform: none;
    left: auto;
    top: auto;
  }

  /* The desktop hover bridge has no purpose in a static sub-list and
     would only add a stray 14px hit area. */
  .products-menu::before {
    content: none;
  }

  /* Flatten the mega menu into a plain vertical list of product links.
     The desktop layout (icon + category heading + description + a row of
     rounded chips) carries far too much furniture for a phone panel, and
     the chips wrap into an unreadable block. Here every product becomes
     one full-width row: Desktops, Monitors, Keyboards, Mouse, and so on. */
  .products-menu-group {
    display: block;
  }

  .products-menu-group + .products-menu-group {
    margin-top: 0;
  }

  /* Icons, blurbs and the category links themselves are all dropped --
     the category pages are still reachable by tapping "Products" a second
     time, which goes to the full products page. */
  .products-menu .menu-category-icon,
  .products-menu-group p,
  .site-nav .products-menu .menu-category-link {
    display: none;
  }

  .products-menu .menu-links {
    display: flex;
    flex-direction: column;
    gap: 0;
  }

  /* Override the desktop pill/chip treatment -- these are list rows now. */
  .site-nav .products-menu .menu-links a {
    display: block;
    padding: 12px 2px;
    color: var(--accent-dark);
    background: none;
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    font-size: 0.98rem;
    font-weight: 650;
  }

  .site-nav .products-menu .menu-links a:hover,
  .site-nav .products-menu .menu-links a:focus-visible {
    color: var(--accent-dark);
    background: none;
  }

  /* The panel's own bottom border already closes the group off. */
  .products-menu-group:last-child .menu-links a:last-child {
    border-bottom: 0;
  }

  .aio-hero {
    min-height: auto;
  }

  .workstation-hero {
    min-height: auto;
    text-align: left;
    place-items: start;
  }

  .workstation-hero .breadcrumb {
    position: static;
    margin-bottom: 40px;
  }

  .workstation-hero .hero-actions {
    justify-content: flex-start;
  }

  .aio-hero > img {
    min-height: 300px;
  }

  .aio-series-picker,
  .aio-feature-grid,
  .aio-review-grid,
  .aio-spec-grid {
    grid-template-columns: 1fr;
  }

  .aio-series-status {
    align-items: flex-start;
    flex-wrap: wrap;
  }

  .aio-series-status a {
    width: 100%;
    margin-left: 44px;
  }

  .aio-showcase {
    margin-inline: 14px;
  }

  .aio-option {
    flex: 1 1 140px;
  }

  .aio-live-summary dl div {
    align-items: flex-start;
  }

  .peripherals-hero {
    min-height: 680px;
  }

  .peripherals-hero > img {
    min-height: 680px;
  }

  .peripherals-hero-overlay {
    background: linear-gradient(0deg, rgba(0, 34, 52, 0.94) 0%, rgba(3, 84, 127, 0.62) 70%, rgba(3, 84, 127, 0.12) 100%);
  }

  .peripherals-hero h1 {
    font-size: clamp(3rem, 15vw, 4.6rem);
  }

  .peripheral-family-card,
  .peripheral-family-card:nth-child(even) {
    grid-template-columns: 1fr;
  }

  .peripheral-family-card:nth-child(even) img,
  .peripheral-family-card:nth-child(even) > div {
    grid-column: 1;
    grid-row: auto;
  }

  .peripheral-family-card img {
    height: 280px;
  }

  .peripheral-picks-grid {
    grid-template-columns: 1fr;
  }

  .peripheral-use-grid article {
    grid-template-columns: 38px 1fr;
  }

  .peripheral-benefit-list article {
    grid-template-columns: 44px 1fr;
  }

  .keyboard-hero {
    min-height: auto;
    text-align: center;
    place-items: start;
  }

  .monitor-hero {
    min-height: auto;
    text-align: left;
    place-items: start;
  }

  .mouse-hero {
    min-height: auto;
    text-align: center;
    place-items: start;
  }

  .monitor-hero .breadcrumb {
    position: static;
    margin-bottom: 40px;
  }

  .keyboard-hero .hero-actions,
  .mouse-hero .hero-actions {
    justify-content: center;
  }

  .monitor-hero .hero-actions {
    justify-content: flex-start;
  }

  .keyboard-card-grid,
  .keyboard-feature-grid,
  .keyboard-review-grid,
  .monitor-card-grid,
  .monitor-feature-grid,
  .monitor-review-grid,
  .monitor-why-grid,
  .mouse-card-grid,
  .mouse-feature-grid,
  .mouse-review-grid,
  .mouse-why-grid {
    grid-template-columns: 1fr;
  }

  .keyboard-product-card,
  .monitor-product-card,
  .mouse-product-card {
    min-height: auto;
    padding: 24px;
  }

  .keyboard-detail-card,
  .monitor-detail-card,
  .monitor-overview-card,
  .monitor-why-grid article,
  .mouse-detail-card,
  .mouse-overview-card,
  .mouse-why-grid article {
    padding: 24px;
  }

  .keyboard-spec-list div,
  .monitor-spec-list div,
  .monitor-overview-card dl div,
  .mouse-spec-list div,
  .mouse-overview-card dl div {
    grid-template-columns: 1fr;
    gap: 4px;
  }

  .keyboard-spec-list dd,
  .monitor-spec-list dd,
  .monitor-overview-card dd,
  .mouse-spec-list dd,
  .mouse-overview-card dd {
    text-align: left;
  }

  .keyboard-detail-visual,
  .monitor-detail-visual,
  .mouse-detail-visual {
    min-height: 260px;
  }

  /* (The mobile hover rule that used to live here has been removed. The
     Products menu is now a static, tap-expanded sub-list at this
     breakpoint -- see the .products-menu block above -- so a hover-driven
     transform would only fight the new layout.) */

  .product-hero {
    min-height: auto;
  }

  .hero-media,
  .hero-media img {
    min-height: 300px;
  }

  .hero-bg {
    min-height: 520px;
  }

  .hero-bg-overlay {
    background: linear-gradient(
      to right,
      var(--paper) 0%,
      var(--paper) 55%,
      rgba(247, 250, 248, 0.75) 68%,
      rgba(247, 250, 248, 0.25) 85%,
      rgba(247, 250, 248, 0) 100%
    );
  }

  .product-grid,
  .model-grid,
  .pricing-grid,
  .feature-list,
  .spec-grid,
  .option-grid.three-col,
  .peripheral-grid,
  .mini-specs,
  .mini-specs.two,
  .mini-specs.three,
  .io-ports-cols {
    grid-template-columns: 1fr;
  }

  .model-search-panel {
    padding: 20px;
  }

  .search-button {
    position: static;
    width: max-content;
  }

  .summary-panel {
    padding: 18px;
  }

  .summary-panel dl div {
    grid-template-columns: 1fr;
    gap: 4px;
  }

  .summary-panel dd {
    text-align: left;
  }

  .category-layout img {
    min-height: 300px;
  }

  .product-card {
    min-height: auto;
  }

  .contact-card {
    grid-template-columns: 1fr;
    border-radius: 16px;
  }

  .contact-grid {
    grid-template-columns: 1fr;
  }

  .form-row {
    grid-template-columns: 1fr;
  }

  .contact-form-panel {
    padding: 20px;
  }

  .contact-form-submit-row {
    justify-content: stretch;
  }

  .contact-form-submit-row .button {
    width: 100%;
  }

  .model-lock-status {
    flex-wrap: wrap;
  }

  .model-lock-status .button.small {
    width: 100%;
  }

  .desktop-model-row {
    margin-inline: -18px;
    padding-inline: 18px;
    max-width: none;
  }
}

/* Interactive Panel configurator -- "Key Specifications" card, styled to
   match the peripheral pages' monitor-spec-list card (dark blue gradient,
   label/value rows with divider lines). */
.panel-spec-card {
  padding: clamp(20px, 4vw, 30px);
  color: #fff;
  background: linear-gradient(135deg, #6b7cab, #03547f 74%, #253290);
  border-radius: 8px;
}

.panel-spec-card h3 {
  margin: 0 0 16px;
  color: #fff;
}

.panel-spec-sheet {
  display: grid;
  gap: 0;
  margin: 0;
}

.panel-spec-sheet div {
  display: grid;
  grid-template-columns: minmax(130px, 0.5fr) minmax(0, 1fr);
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.22);
}

.panel-spec-sheet div:last-child {
  border-bottom: none;
}

.panel-spec-sheet dt {
  color: rgba(255, 255, 255, 0.72);
  font-weight: 750;
}

.panel-spec-sheet dd {
  margin: 0;
  color: #fff;
  font-weight: 850;
  text-align: right;
  overflow-wrap: anywhere;
}

@media (max-width: 720px) {
  .panel-spec-sheet div {
    grid-template-columns: 1fr;
    gap: 4px;
  }

  .panel-spec-sheet dd {
    text-align: left;
  }
}

/* Interactive Panel nav dropdown icon -- small dot centered in the icon
   rectangle, representing a touch point (distinct from the pc/peripheral
   icons' bottom-line and mid-line marks). */
.menu-panel-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  background: #03547f;
  border-radius: 999px;
}

/* Digital Signage nav dropdown icon -- small filled rectangle centered in
   the icon frame, representing a standee/wall-mount display panel
   (distinct from the pc/peripheral/panel icons' other marks). */
.menu-signage-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 6px;
  margin: -3px 0 0 -4px;
  background: #03547f;
  border-radius: 1px;
}

/* Custom trailing cursor ring (cursor-fx.js). The normal system arrow
   stays visible -- this is a thin outlined ring that lags slightly
   behind it, and morphs into a rounded box around links/buttons on
   hover. Injected by JS and stays hidden/opacity:0 until the first real
   mousemove fires, so nothing shows on touch devices or before the
   script loads. */
.cursor-fx-ring {
  position: fixed;
  top: 0;
  left: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1.5px solid rgba(20, 32, 29, 0.55);
  pointer-events: none;
  z-index: 9999;
  opacity: 0;
  transition: opacity 0.25s ease, border-color 0.25s ease;
  will-change: transform, width, height, border-radius;
}

.cursor-fx-ring.is-hover {
  border-color: var(--accent);
}

/* Water-ripple cursor trail (water-ripple.js), homepage only. Full-screen
   canvas overlay; pointer-events:none so it never blocks clicks, taps, or
   any button/link underneath it. */
.water-ripple-canvas {
  position: fixed;
  inset: 0;
  /* Must stay BELOW .site-header's z-index: 10. This canvas uses
     mix-blend-mode, which makes the compositor blend it against a
     captured snapshot of everything painted beneath it. When it sat at
     z-index: 9997 it covered the open products dropdown too, and while
     the dropdown's opacity/visibility transition was creating/destroying
     its composited layer, Chrome could blend against a STALE snapshot
     from before the menu was painted -- which showed the hero carousel
     "bleeding through" the menu's solid white background in the nav bar.
     Keeping the canvas under the header removes the menu from its
     backdrop entirely, so that misrender can't happen. The ripple is a
     page-background effect anyway, so losing it over the nav is fine. */
  z-index: 5;
  pointer-events: none;
  /* screen only ever brightens what's underneath (opposite of multiply),
     so a warm highlight color reads as a soft glow/sheen against the
     cream page background instead of a dark smudge. */
  mix-blend-mode: screen;
}

/* Scroll-reveal (desktop-scroll-reveal.js), Desktop PCs page only --
   each top-level section fades up into place the first time it scrolls
   into view. .reveal-stagger children (cards inside a revealed section)
   cascade in one after another instead of popping in together. */
.reveal-section {
  opacity: 0;
  transform: translateY(36px);
  transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

.reveal-section.is-visible {
  opacity: 1;
  /* `none` (not translateY(0)): a lingering no-op transform kept every
     revealed section -- including the homepage hero right under the nav
     -- promoted as its own stacking context/composited layer forever,
     which fed the same stale-layer compositing glitch behind the
     products dropdown. Transitions interpolate none as the identity
     transform, so the reveal animation itself is unchanged. */
  transform: none;
}

.reveal-section .reveal-stagger {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.reveal-section.is-visible .reveal-stagger {
  opacity: 1;
  transform: none; /* same reasoning as .reveal-section.is-visible above */
}

.reveal-section.is-visible .reveal-stagger:nth-child(1) { transition-delay: 0.05s; }
.reveal-section.is-visible .reveal-stagger:nth-child(2) { transition-delay: 0.15s; }
.reveal-section.is-visible .reveal-stagger:nth-child(3) { transition-delay: 0.25s; }
.reveal-section.is-visible .reveal-stagger:nth-child(4) { transition-delay: 0.35s; }
.reveal-section.is-visible .reveal-stagger:nth-child(5) { transition-delay: 0.45s; }

@media (prefers-reduced-motion: reduce) {
  .reveal-section,
  .reveal-section .reveal-stagger {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Scroll-linked image zoom (see scroll-zoom.js). GSAP drives the actual
   scale/translateY via inline style on each .scroll-zoom-img -- these
   rules are just performance hints for the browser's compositor and the
   reduced-motion fallback. */
.scroll-zoom-img,
.scroll-zoom-card {
  will-change: transform;
  backface-visibility: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .scroll-zoom-img,
  .scroll-zoom-card {
    transform: none !important;
  }
}

/* Homepage -- combined "About Litset" section: three equal-size panels
   side by side (photo pair / About intro / Why Litset). Equal width comes
   from `flex: 1 1 0` on all three; equal height comes from flexbox's
   default `align-items: stretch` -- the tallest panel's natural content
   height (normally the Why Litset card, with its 4-item list) sets the
   height for all three, matched to the tallest one's real content (the Why
   Litset card) -- so every slot is always the "big" size, not just
   whichever currently sits in the middle. about-collage.js still rotates
   which of the three sits in the middle every 5s (a FLIP-animated slide),
   the middle slot just gets a slight elevation now rather than a size
   change. The photo pair inside the photos slot separately auto-cycles
   through several image sets. */
.about-collage {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: clamp(16px, 2.4vw, 28px);
  max-width: 1800px;
  margin: 0 auto;
  padding: 44px 0 36px;
}

/* Shared sizing/position rules for the three rotating slots. Actual size
   comes from align-items: stretch above (all three match the tallest
   sibling's real content, the Why Litset card -- including the photos
   slot, whose slides are absolutely positioned and so have no content
   height of their own to stretch from). .is-mid (toggled by
   about-collage.js) only bumps elevation, not size. */
.about-collage-slot {
  flex: 1 1 0;
  min-width: 220px;
  transition: transform 0.6s ease;
}

.about-collage-slot.is-mid {
  z-index: 4;
}

.about-collage-photos {
  position: relative;
  overflow: hidden;
  border-radius: 16px;
  box-shadow: var(--shadow);
}

.about-collage-slide {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-rows: 1.15fr 1fr;
  gap: 8px;
  opacity: 0;
  transform: translateX(-100%);
  transition: transform 0.7s ease, opacity 0.7s ease;
}

.about-collage-slide.is-active {
  opacity: 1;
  transform: translateX(0);
  z-index: 2;
}

.about-collage-slide.is-prev {
  opacity: 0;
  transform: translateX(100%);
  z-index: 1;
}

.about-collage-photo {
  position: relative;
  overflow: hidden;
}

.about-collage-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.about-collage-panel {
  position: relative;
  padding: clamp(28px, 3.5vw, 44px) clamp(24px, 3vw, 34px);
  color: #fff;
  background: var(--accent-dark);
  border-radius: 18px;
  box-shadow: 0 26px 54px rgba(20, 32, 29, 0.3);
}

.about-collage-heading {
  margin: 0 0 18px;
  font-size: clamp(1.7rem, 2.6vw, 2.2rem);
  font-weight: 800;
  color: #fff;
  line-height: 1.1;
}

.about-collage-panel > p:not(.about-collage-heading) {
  margin: 0 0 16px;
  color: rgba(255, 255, 255, 0.82);
  line-height: 1.65;
  font-size: 0.92rem;
}

.about-collage-cta {
  display: inline-flex;
  margin-top: 4px;
  color: #fff;
  background: rgba(0, 0, 0, 0.28);
  border: 1px solid rgba(255, 255, 255, 0.32);
}

.about-collage-card {
  position: relative;
  padding: clamp(28px, 3.5vw, 44px);
  background: #fff;
  border-radius: 18px;
  box-shadow: var(--shadow);
  overflow: hidden;
}

.about-why-intro {
  margin: 14px 0 26px;
  color: var(--muted);
  line-height: 1.7;
  max-width: 52ch;
}

.about-why-list {
  display: grid;
  gap: 18px;
}

.about-why-item {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}

.about-why-icon {
  display: grid;
  flex: 0 0 auto;
  place-items: center;
  width: 44px;
  height: 44px;
  color: var(--accent-dark);
  background: var(--sky);
  border-radius: 50%;
}

.about-why-icon svg {
  width: 20px;
  height: 20px;
}

.about-why-item h3 {
  margin-bottom: 4px;
}

.about-why-item p {
  margin: 0;
  color: var(--muted);
  line-height: 1.6;
  font-size: 0.94rem;
}

@media (prefers-reduced-motion: reduce) {
  .about-collage-slide,
  .about-collage-slot {
    transition: none !important;
  }
}

/* Below ~1100px the equal-height stretch (driven by the tallest panel's
   real content) gets too tall for 3 side-by-side columns to stay
   readable, so it collapses to a simple stacked column instead. */
@media (max-width: 1100px) {
  .about-collage {
    flex-direction: column;
    align-items: stretch;
    gap: 20px;
  }

  .about-collage-panel {
    order: -1;
  }

  .about-collage-slot.is-mid {
    z-index: auto;
  }

  /* Stacked layout fix.
     .about-collage-slot keeps `flex: 1 1 0` from the desktop rule, but once
     the container is flex-direction: column that `0` is a *height* basis,
     not a width one -- so each slot starts at zero height and relies on
     flex-grow to distribute space that an auto-height container doesn't
     have. The result is slots that collapse or size unpredictably, which is
     why the photos and the Why Litset card were coming out empty or clipped
     while only the About panel rendered.
     `flex: 0 0 auto` drops the grow/shrink entirely and lets each slot take
     its natural content height, which is what stacking wants. */
  .about-collage-slot {
    flex: 0 0 auto;
    width: 100%;
    min-width: 0;
  }

  /* Absolutely-positioned slides give this slot no content height of its
     own, so it needs an explicit one. aspect-ratio scales with the screen
     instead of a fixed 360px that's too tall on a small phone. */
  .about-collage-photos {
    aspect-ratio: 4 / 3;
    height: auto;
    min-height: 260px;
  }

  /* These carry real content; make sure nothing clips it once stacked. */
  .about-collage-panel,
  .about-collage-card {
    height: auto;
    overflow: visible;
  }
}

/* Homepage -- combined "What We Supply" + "Who We Serve" section.
   industries-tabs.js auto-advances through the 4 industry tabs every 6s
   (pausing on hover/focus, resetting when a tab is clicked), crossfading
   the photo pair and the copy block below to match -- same family of
   crossfade as the About collage's photo cycle, so it reads as one
   consistent motion language across the homepage. */
.industries-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  max-width: 1800px;
  margin: 0 auto 32px;
}

.industries-tab {
  padding: 11px 20px;
  color: var(--muted);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.92rem;
  font-weight: 700;
  cursor: pointer;
  transition: color 0.2s ease, background 0.2s ease, border-color 0.2s ease;
}

.industries-tab:hover {
  color: var(--accent-dark);
  border-color: var(--accent-dark);
}

.industries-tab.is-active {
  color: #fff;
  background: var(--accent-dark);
  border-color: var(--accent-dark);
}

.industries-panel {
  display: flex;
  align-items: stretch;
  gap: clamp(20px, 3vw, 40px);
  max-width: 1800px;
  margin: 0 auto;
}

.industries-photo {
  position: relative;
  flex: 1 1 0;
  min-width: 280px;
  height: 460px;
  overflow: hidden;
  border-radius: 20px;
  background: var(--paper);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
}

.industries-photo-slide {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: 8px;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.industries-photo-slide.is-active {
  opacity: 1;
  z-index: 1;
}

.industries-photo-slide > img {
  display: block;
  width: 100%;
  height: 100%;
  /* The box is a fixed 460px tall against a fluid width, so its shape ranges
     from about 1.5:1 to 1.9:1 while the photos are 4:3 -- `cover` therefore
     trims the top and bottom, and how much depends on the window width.

     Biased below centre because the subject of every one of these photos (a
     display, a desk) sits in the lower half of the frame while the upper
     part is ceiling and empty wall. At the widest the visible band works out
     to roughly 18%-87% of the photo; the retail display occupies 29%-78%, so
     it clears both edges with margin to spare at every width.

     These images also carry data-no-scroll-zoom in the markup. The site-wide
     scroll effect scales images up to 1.15x, which narrowed that band to
     19.7%-80.3% and left only ~2% of clearance under the display -- enough
     that it clipped on wide screens. The zoom buys little inside a tabbed
     panel where the photo changes on click rather than on scroll. */
  object-fit: cover;
  object-position: center 58%;
}

/* Slides with only one real photo (Retail & Public Spaces has just the one
   signage shot) get the single-row treatment explicitly, rather than
   relying on :has() support to detect it. */
.industries-photo-slide.is-single {
  grid-template-rows: 1fr;
}


.industries-copy {
  position: relative;
  flex: 1 1 0;
  min-width: 280px;
  min-height: 460px;
}

.industries-copy-slide {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.industries-copy-slide.is-active {
  opacity: 1;
  z-index: 1;
}

.industries-copy-slide h3 {
  margin-bottom: 12px;
}

.industries-copy-slide p {
  margin: 0;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1.7;
  max-width: 46ch;
}

.industries-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 22px;
}

.industries-chip {
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  color: var(--accent-dark);
  background: var(--sky);
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 700;
  transition: background 0.2s ease, color 0.2s ease;
}

.industries-chip:hover {
  color: #fff;
  background: var(--accent-dark);
}

/* Bump up every text element in this section -- scoped to #industries so
   the shared .eyebrow/.industries-tab/etc. classes stay their normal size
   everywhere else on the site. */
#industries .eyebrow {
  font-size: 1.5rem;
}

#industries .industries-tab {
  padding: 13px 24px;
  font-size: 1.05rem;
}

#industries .industries-copy-slide h3 {
  font-size: 1.7rem;
}

#industries .industries-copy-slide p {
  font-size: 1.2rem;
}

#industries .industries-chip {
  padding: 10px 20px;
  font-size: 1rem;
}

@media (max-width: 780px) {
  .industries-panel {
    flex-direction: column;
  }

  .industries-photo {
    height: 320px;
  }

  .industries-copy {
    min-height: 0;
    position: static;
  }

  .industries-copy-slide {
    position: static;
    display: none;
    opacity: 1;
  }

  .industries-copy-slide.is-active {
    display: flex;
  }
}

@media (prefers-reduced-motion: reduce) {
  .industries-tab,
  .industries-photo-slide,
  .industries-copy-slide {
    transition: none !important;
  }
}

/* Homepage -- "Our Working Process" 3-step strip. Centered heading, then a
   row of icon-badge-over-card steps connected by dashed arrows -- the
   middle step (Quote & Direct Billing) is visually featured: a darker,
   larger badge, a dark filled card, and a slight lift above its neighbours. */
.process-heading {
  max-width: 720px;
  margin: 0 auto 44px;
  text-align: center;
}

.process-heading h2 {
  margin: 0 0 12px;
}

.process-heading p {
  margin: 0;
  color: var(--muted);
  line-height: 1.6;
}

.process-steps {
  display: flex;
  align-items: flex-start;
  gap: clamp(8px, 2vw, 24px);
  max-width: 1800px;
  margin: 0 auto;
  padding-top: 38px;
}

.process-step {
  position: relative;
  flex: 1;
  min-width: 0;
  transition: transform 0.3s ease;
}

.process-step-icon {
  position: absolute;
  top: -38px;
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  place-items: center;
  width: 76px;
  height: 76px;
  color: var(--accent-dark);
  background: var(--sky);
  border-radius: 50%;
  box-shadow: 0 10px 22px rgba(20, 32, 29, 0.16);
  z-index: 2;
}

.process-step-icon svg {
  width: 30px;
  height: 30px;
}

.process-step-card {
  height: 100%;
  padding: 46px 22px 28px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 14px;
  text-align: center;
}

.process-step-card h3 {
  margin-bottom: 8px;
}

.process-step-card p {
  margin: 0;
  color: var(--muted);
  line-height: 1.6;
  font-size: 0.94rem;
}

.process-step.is-featured {
  transform: translateY(-16px);
  z-index: 1;
}

.process-step.is-featured .process-step-icon {
  width: 88px;
  height: 88px;
  color: #fff;
  background: var(--accent-dark);
  box-shadow: 0 14px 28px rgba(20, 32, 29, 0.28);
}

.process-step.is-featured .process-step-icon svg {
  width: 34px;
  height: 34px;
}

.process-step.is-featured .process-step-card {
  padding-top: 52px;
  padding-bottom: 40px;
  color: #fff;
  background: var(--accent-dark);
  border-color: var(--accent-dark);
  box-shadow: 0 26px 48px rgba(20, 32, 29, 0.24);
}

.process-step.is-featured .process-step-card h3 {
  color: #fff;
}

.process-step.is-featured .process-step-card p {
  color: rgba(255, 255, 255, 0.82);
}

.process-arrow {
  flex: 0 0 auto;
  align-self: flex-start;
  width: clamp(28px, 3.5vw, 56px);
  height: 0;
  margin-top: 36px;
  border-top: 2px dashed var(--line);
}

.process-arrow::after {
  content: "";
  display: block;
  margin-top: -5px;
  margin-left: 100%;
  width: 0;
  height: 0;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 6px solid var(--line);
}

@media (max-width: 900px) {
  .process-steps {
    flex-direction: column;
    align-items: stretch;
    gap: 44px;
  }

  .process-step.is-featured {
    transform: none;
  }

  .process-arrow {
    display: none;
  }
}

/* Homepage -- "Quick Quote" dark panel with an inline lead form (posts to
   the same /api/contact-lead/ endpoint the Contact page form uses). The
   form itself reuses the shared .form-field/.form-row/.form-status
   classes; only label/hint colors need overriding for the dark panel. */
.quick-quote-section {
  display: grid;
  grid-template-columns: minmax(260px, 0.7fr) minmax(320px, 1fr);
  align-items: stretch;
  padding: 0;
  overflow: hidden;
  border-radius: 20px;
  max-width: 1800px;
  margin: clamp(52px, 8vw, 104px) auto;
}

.quick-quote-media {
  overflow: hidden;
}

.quick-quote-media img {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 360px;
  object-fit: cover;
}

.quick-quote-panel {
  padding: clamp(28px, 4vw, 48px);
  color: #fff;
  background: var(--accent-dark);
}

.quick-quote-panel .eyebrow {
  color: rgba(255, 255, 255, 0.7);
}

.quick-quote-panel > p:not(.eyebrow) {
  margin: 14px 0 0;
  color: rgba(255, 255, 255, 0.78);
  line-height: 1.6;
}

.quick-quote-form {
  margin-top: 24px;
}

.quick-quote-panel .form-field label {
  color: rgba(255, 255, 255, 0.9);
}

.quick-quote-panel .form-hint {
  color: rgba(255, 255, 255, 0.6);
}

.quick-quote-panel button[type="submit"] {
  width: 100%;
  margin-top: 22px;
}

@media (max-width: 900px) {
  .quick-quote-section {
    grid-template-columns: 1fr;
  }

  .quick-quote-media img {
    min-height: 220px;
  }
}

/* Footer -- newsletter signup strip above the main footer columns. */
.footer-newsletter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 28px clamp(18px, 4vw, 64px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.footer-newsletter-copy h3 {
  margin: 0 0 4px;
  color: #fff;
}

.footer-newsletter-copy p {
  margin: 0;
  color: rgba(255, 255, 255, 0.68);
  font-size: 0.92rem;
}

.newsletter-form {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.newsletter-form input[type="email"] {
  min-width: 240px;
  padding: 11px 14px;
  color: var(--ink);
  background: #fff;
  border: 1px solid transparent;
  border-radius: 8px;
  font: inherit;
  font-size: 0.94rem;
}

.footer-newsletter .form-status {
  flex-basis: 100%;
  margin: 0;
}

@media (max-width: 640px) {
  .footer-newsletter {
    flex-direction: column;
    align-items: stretch;
  }

  .newsletter-form {
    flex-direction: column;
  }
}

/* Homepage -- cinematic "Our Presence" section. A real aerial terrain
   photo (licensed for this use) sits as a single ground layer, panned and
   scaled by presence.js's GSAP camera, with a top pins layer on top that
   always stays pixel-precise. Camera targets are laid out in the same
   0-325.12 x 0-407.24664 coordinate space used elsewhere on this site for
   Chhattisgarh's real relative geography, so the 9 city pins keep sensible
   real-world spacing even though the ground itself is now a photo rather
   than a literal state-shaped illustration. */
/* Intro copy above the map: heading fades in first, then the paragraph
   reveals line by line, then the scroll cue -- all keyed off the section's
   existing .is-visible toggle (scroll-reveal.js), so no extra JS is needed.
   It stays in place afterwards (no fade-out/collapse once revealed). */
.presence-intro {
  max-width: 960px;
  margin: 0 auto clamp(32px, 5vw, 56px);
  text-align: center;
}

.presence-intro-eyebrow,
.presence-intro-title,
.presence-intro-copy .presence-intro-line,
.presence-scroll-cue {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

#presence-map-alt.is-visible .presence-intro-eyebrow,
#presence-map-alt.is-visible .presence-intro-title,
#presence-map-alt.is-visible .presence-intro-copy .presence-intro-line,
#presence-map-alt.is-visible .presence-scroll-cue {
  opacity: 1;
  transform: translateY(0);
}

#presence-map-alt.is-visible .presence-intro-eyebrow { transition-delay: 0s; }
#presence-map-alt.is-visible .presence-intro-title { transition-delay: 0.12s; }
#presence-map-alt.is-visible .presence-intro-copy .presence-intro-line:nth-child(1) { transition-delay: 0.38s; }
#presence-map-alt.is-visible .presence-intro-copy .presence-intro-line:nth-child(2) { transition-delay: 0.5s; }
#presence-map-alt.is-visible .presence-intro-copy .presence-intro-line:nth-child(3) { transition-delay: 0.62s; }
#presence-map-alt.is-visible .presence-intro-copy .presence-intro-line:nth-child(4) { transition-delay: 0.74s; }
#presence-map-alt.is-visible .presence-scroll-cue { transition-delay: 0.95s; }

.presence-intro-eyebrow {
  margin: 0 0 10px;
  color: var(--accent-dark);
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.presence-intro-title {
  margin: 0 0 18px;
  white-space: nowrap;
}

@media (max-width: 640px) {
  .presence-intro-title {
    white-space: normal;
  }
}

.presence-intro-copy {
  margin: 0 0 26px;
  color: var(--muted);
  font-size: 1.2rem;
  line-height: 1.7;
}

.presence-intro-line {
  display: inline-block;
}

.presence-scroll-cue {
  display: inline-flex;
  color: var(--accent-dark);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.03em;
}

/* The pulse lives on this inner wrapper, separate from .presence-scroll-cue
   itself, so the always-running keyframe animation doesn't fight with the
   one-time entrance transition (opacity/transform) on the outer link. */
.presence-scroll-cue-inner {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  animation: presence-scroll-cue-pulse 2.2s ease-in-out infinite;
}

.presence-scroll-cue svg {
  width: 18px;
  height: 18px;
}

@keyframes presence-scroll-cue-pulse {
  0%, 100% { opacity: 0.55; transform: translateY(0); }
  50% { opacity: 1; transform: translateY(5px); }
}

@media (prefers-reduced-motion: reduce) {
  .presence-intro,
  .presence-intro-eyebrow,
  .presence-intro-title,
  .presence-intro-copy .presence-intro-line,
  .presence-scroll-cue {
    transition: none;
  }

  .presence-scroll-cue-inner {
    animation: none;
  }
}

.presence-stage {
  position: relative;
  max-width: 1280px;
  margin: 0 auto;
  border-radius: 20px;
  overflow: hidden;
  background: #241c14;
  border: 1px solid var(--line);
  aspect-ratio: 16 / 10;
  /* The "Scroll to Explore" link jumps to this element's native anchor
     position (its very top edge) -- without this, the sticky 88px header
     covers that same amount of the stage after scrolling, so the top of
     the map appears to have "gone upwards" behind it. */
  scroll-margin-top: 108px;
}

.presence-viewport {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.presence-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  transform-origin: 0 0;
  will-change: transform;
}

.presence-layer-photo {
  overflow: hidden;
}

.presence-photo-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Soft vignette so pins and the glassmorphism card stay legible over
   whatever part of the photo the camera is framing. */
.presence-layer-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(20, 15, 8, 0.35) 0%, rgba(20, 15, 8, 0) 30%, rgba(20, 15, 8, 0) 60%, rgba(20, 15, 8, 0.45) 100%);
}

/* Pins: plain positioned HTML (not SVG) so the city coordinate space
   never has to be reconciled with the stage's own aspect ratio via
   preserveAspectRatio -- that reconciliation ("slice" mode) was silently
   cropping out pins far from vertical center, like Jagdalpur. Left/top
   percentages have no such cropping at any aspect ratio. Each pin is a
   small diamond mark plus a one-shot ripple ring. */
.presence-pins {
  position: absolute;
  inset: 0;
}

.presence-pin {
  position: absolute;
  width: 1px;
  height: 1px;
  cursor: pointer;
  outline: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.4);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.presence-pin.is-revealed {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.presence-pin-dot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 20px;
  height: 20px;
  background: #ffb545;
  border: 2.5px solid #fff;
  transform: translate(-50%, -50%) rotate(45deg);
  box-shadow: 0 0 8px rgba(255, 181, 69, 0.9);
  transition: background 0.2s ease;
}

.presence-pin.is-idle-glow .presence-pin-dot {
  animation: presence-idle-pulse 2.6s ease-in-out infinite;
}

.presence-pin.is-active .presence-pin-dot {
  background: #fff;
}

.presence-pin-ripple {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  border: 2px solid #ffb545;
  border-radius: 50%;
  opacity: 0;
}

.presence-pin.is-rippling .presence-pin-ripple {
  animation: presence-ripple 1.1s ease-out 1;
}

@keyframes presence-ripple {
  0% { opacity: 0.9; transform: scale(0.3); }
  100% { opacity: 0; transform: scale(3.4); }
}

@keyframes presence-idle-pulse {
  0%, 100% { box-shadow: 0 0 6px rgba(255, 181, 69, 0.9); }
  50% { box-shadow: 0 0 12px rgba(255, 181, 69, 1); }
}

.presence-card-slot {
  position: absolute;
  top: 50%;
  right: clamp(14px, 3vw, 28px);
  left: clamp(14px, 3vw, 28px);
  transform: translateY(-50%);
  display: flex;
  justify-content: flex-end;
  pointer-events: none;
  z-index: 2;
}

.presence-card {
  pointer-events: auto;
  width: min(280px, 100%);
  padding: 20px 22px;
  border-radius: 14px;
  background: rgba(36, 28, 20, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.35);
  color: #fff;
  opacity: 0;
}

.presence-card-city {
  margin: 0 0 8px;
  font-size: 1.2rem;
  font-weight: 800;
}

.presence-card-products {
  margin: 0 0 10px;
  color: rgba(255, 255, 255, 0.78);
  line-height: 1.6;
  font-size: 0.92rem;
}

.presence-card-status-line {
  margin: 0 0 14px;
}

.presence-card-status {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  background: rgba(255, 181, 69, 0.18);
  color: #ffb545;
  font-size: 0.78rem;
  font-weight: 750;
}

.presence-skip {
  position: absolute;
  bottom: 18px;
  left: 18px;
  z-index: 3;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: rgba(36, 28, 20, 0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: #fff;
  font-size: 0.8rem;
  font-weight: 650;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.presence-skip:hover {
  border-color: #ffb545;
  background: rgba(36, 28, 20, 0.75);
}

@media (max-width: 720px) {
  .presence-stage {
    aspect-ratio: 4 / 5;
    border-radius: 14px;
  }

  .presence-card {
    width: 100%;
  }

  .presence-card-slot {
    top: auto;
    bottom: 60px;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .presence-layer {
    transition: none !important;
  }

  .presence-pin-dot {
    animation: none !important;
  }
}

/* ===========================================================================
   MOBILE SAFETY PASS (<=720px)
   ---------------------------------------------------------------------------
   Two classes of problem showed up on a real phone:

   1. Headings with `white-space: nowrap`. These were set for desktop, where
      the line genuinely fits. On a phone they cannot wrap, so they run past
      the screen edge and drag the whole page sideways.

   2. Headings sized with clamp(min, Xvw, max) where the MINIMUM was tuned
      for desktop. On a narrow screen the vw term shrinks, so the size floors
      at that minimum -- leaving 46-58px text on a ~390px-wide screen.
      The fix is to lower the floor at this breakpoint only; the vw term then
      does the scaling it was always meant to do.

   Deliberately last in the file so these overrides win on cascade ties.
   Nothing here affects layouts above 720px.
   ========================================================================= */
@media (max-width: 720px) {
  /* --- 1. let long headings wrap instead of overflowing --- */
  .hero-slide-primary h1,
  #about-hero .about-hero-primary .hero-copy h1,
  .presence-intro-title {
    white-space: normal;
  }

  /* 11ch is a deliberate, tight measure on desktop; on a phone it forces
     roughly two words per line and makes headings absurdly tall. */
  h1 {
    max-width: none;
  }

  /* --- 2. bring oversized heading floors down to phone scale --- */
  h1 {
    font-size: clamp(1.9rem, 7.5vw, 2.6rem);
  }

  #contact-hero .hero-copy h1,
  .monitor-hero h1,
  .peripherals-hero h1,
  .aio-hero h1,
  .workstation-hero h1,
  .category-layout h1,
  #about-hero .about-hero-primary .hero-copy h1 {
    font-size: clamp(1.75rem, 7vw, 2.5rem);
  }

  /* 5.4vw keeps the longest forced line ("Reliable Litset desktops") inside
     the ~68% copy column, so the heading stays the three lines its <br>
     breaks intend rather than wrapping to four. See the note further down
     for the full working. */
  .desktop-hero-content h2 {
    font-size: clamp(1.05rem, 5.4vw, 1.95rem);
  }

  /* Supporting hero copy scaled to match, so the ratio to the heading
     stays sensible rather than the body text looking oversized next to a
     now-smaller title. */
  #about-hero .about-hero-primary .hero-copy > p {
    font-size: 1rem;
  }

  #about-hero .about-hero-primary .hero-trust-badge {
    font-size: 0.9rem;
  }

  #about-hero .about-hero-primary .button {
    min-height: 48px;
    padding: 12px 20px;
    font-size: 1rem;
  }

  /* --- 3. last-resort guard ---
     Catches anything still wider than the viewport so it can't push the
     page sideways.

     `clip`, NOT `hidden`, and on body only. `overflow-x: hidden` forces the
     used value of overflow-y to `auto`, which turns the element into a
     scroll container -- and that breaks `position: sticky` on descendants,
     i.e. it would stop the site header sticking on exactly the devices
     where the mobile nav matters most. `clip` crops without creating a
     scroll container, so sticky keeps working.
     The grids that actually caused the overflow are fixed further down the
     file; this is only a safety net. */
  body {
    overflow-x: clip;
  }
}

/* ===========================================================================
   Interactive Panel line -- configurator hero
   ---------------------------------------------------------------------------
   /product/configure/ is shared by every product line, so this is gated on
   body.line-panel (added by configure.js once the line loads). Digital
   Signage and the PC lines keep the default side-by-side hero.

   Same treatment as the Products page hero: the photo is a full-bleed
   background and the copy sits on top of it, with a white gradient fading
   left-to-right so the text stays legible. Unlike the Products hero, this
   photo has no built-in empty margin -- the classroom runs edge to edge --
   so the gradient carries the legibility on its own and is held fully
   opaque further across before it starts to fall away.
   ========================================================================= */
body.line-panel .category-hero {
  position: relative;
  display: flex;
  align-items: center;
  /* Takes the photo's own 1295x720 proportions so `cover` crops nothing --
     the full classroom is visible at every width, and the panel screen
     stays put at 37.5%-65.3% across, which is what the gradient stops
     below are tuned against. */
  aspect-ratio: 1295 / 720;
  min-height: 0;
  padding: clamp(32px, 6vw, 80px) clamp(18px, 5vw, 72px);
  overflow: hidden;
  background-color: #fff;
  background-image: url("assets/panel-hero-classroom.webp");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: right center;
}

body.line-panel .category-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  /* A softer wash than a solid white block -- the photo stays faintly
     visible behind the copy instead of being painted out.
     Clears at 37%, immediately before the panel screen begins at 37.5%, so
     the product is never veiled. The copy column below is sized to finish
     around 35%, leaving a small margin. */
  background: linear-gradient(
    to right,
    rgba(255, 255, 255, 0.88) 0%,
    rgba(255, 255, 255, 0.84) 22%,
    rgba(255, 255, 255, 0.58) 29%,
    rgba(255, 255, 255, 0.25) 33%,
    rgba(255, 255, 255, 0) 37%
  );
}

/* Frosted-glass layer: blurs the photo behind the copy, masked so the blur
   fades out left-to-right and the classroom stays perfectly sharp on the
   right. Sits below the copy (z-index 2) and above the background image.
   mask-image is what makes the blur gradual -- backdrop-filter on its own
   applies uniformly across the whole element. */
body.line-panel .category-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
  -webkit-mask-image: linear-gradient(
    to right,
    #000 0%,
    #000 22%,
    rgba(0, 0, 0, 0.55) 29%,
    rgba(0, 0, 0, 0.2) 33%,
    transparent 37%
  );
  mask-image: linear-gradient(
    to right,
    #000 0%,
    #000 22%,
    rgba(0, 0, 0, 0.55) 29%,
    rgba(0, 0, 0, 0.2) 33%,
    transparent 37%
  );
}

/* Single column -- the photo replaces the right-hand image slot. */
body.line-panel .category-layout {
  position: relative;
  z-index: 2;
  display: block;
  max-width: 1800px;
  width: 100%;
  overflow: visible;
}

/* The copy occupies the left portion of the hero (over the gradient) and is
   centred within it -- horizontally inside its own column, and vertically
   via the .category-hero flex `align-items: center` above. */
/* Capped at 29% of the width: the panel screen starts at 37.5% and the veil
   clears at 37%, so the copy has to finish before that. This works out to
   ~35% across at every desktop size, leaving a consistent margin. */
body.line-panel .category-layout > div {
  width: min(560px, 29%);
  text-align: center;
}

/* The separate hero <img> is redundant now the photo is the background.
   Hidden rather than removed from the DOM so configure.js can keep
   setting its src without erroring. */
body.line-panel #hero-image {
  display: none;
}

/* auto margins so the constrained heading/paragraph stay centred inside the
   column rather than hugging its left edge. */
/* The 18ch cap is gone and the size ramp is tuned so "Litset Interactive
   Panel" (24 characters) clears the column on a single line rather than
   breaking after each word.
   Deliberately NOT `white-space: nowrap` -- forcing it that way is what
   pushed the About hero off-screen on mobile earlier; sizing it to fit
   keeps one line where there's room and wraps safely where there isn't. */
/* Sized so "Litset Interactive Panel" (24 characters) still clears the
   column on one line at every desktop width -- the column is narrower here
   than on the signage hero, so this can't go as large as that one. */
body.line-panel .category-layout h2 {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  font-size: clamp(1.45rem, 2.1vw, 2.1rem);
  line-height: 1.12;
}

body.line-panel .category-layout p:not(.eyebrow) {
  max-width: 40ch;
  margin: 16px auto 0;
  color: #3d4b5d;
  font-size: clamp(0.98rem, 1.1vw, 1.15rem);
  line-height: 1.68;
}

body.line-panel .category-layout .hero-actions {
  margin-top: 26px;
}

body.line-panel .category-layout .button {
  min-height: 52px;
  padding: 14px 26px;
  font-size: 1.02rem;
}

body.line-panel .category-layout .hero-actions {
  justify-content: center;
}

/* Mid widths: copy and classroom still share the frame -- the text scales
   down with it rather than the veil going solid and painting the photo out.
   The hero keeps the image's aspect ratio, so there's no horizontal crop
   and the panel screen stays at 37.5%, matching the gradient above. */
@media (max-width: 900px) {
  /* A full-hero backdrop-filter is costly on lower-powered devices, and the
     gradient alone carries legibility at this size. */
  body.line-panel .category-hero::after {
    display: none;
  }

  body.line-panel .category-layout h2 {
    font-size: clamp(1.05rem, 2.6vw, 1.5rem);
  }

  body.line-panel .category-layout p:not(.eyebrow) {
    max-width: 30ch;
    margin-top: 8px;
    font-size: clamp(0.78rem, 1.5vw, 0.95rem);
    line-height: 1.5;
  }

  body.line-panel .category-layout .hero-actions {
    margin-top: 14px;
  }

  body.line-panel .category-layout .button {
    min-height: 40px;
    padding: 9px 16px;
    font-size: 0.86rem;
  }

  /* 28%, not 32%: with the section padding included, 32% put the text's
     right edge at exactly 37% -- the same point the veil clears -- so the
     last characters would have sat on unveiled photo. This keeps a ~3%
     margin at every width in this band. */
  body.line-panel .category-layout > div {
    width: min(300px, 28%);
  }
}

/* Phones: no room for copy beside the panel, so the veil goes near-solid
   and the text takes the full width. */
@media (max-width: 620px) {
  body.line-panel .category-hero::before {
    background: rgba(255, 255, 255, 0.9);
  }

  body.line-panel .category-layout > div {
    width: 100%;
  }

  body.line-panel .category-layout h2,
  body.line-panel .category-layout p:not(.eyebrow) {
    max-width: none;
  }
}

/* ===========================================================================
   Interactive Panel -- screen-size feature rows (#panel-size-cards)
   ---------------------------------------------------------------------------
   Full-width rows, image one side and copy the other, stacked one per size,
   instead of the earlier four-up card grid. Markup is generated by
   configurator-engine.js (renderScreenSizeCards) from the live catalog, so
   the row count follows whatever sizes are active in the dashboard.
   Each row is a <button>: choosing one selects that size in the
   configurator below and scrolls to it.
   ========================================================================= */
/* Centred, stacked heading -- the shared .section-heading is a
   left-eyebrow / right-copy row, which reads oddly above full-width
   feature rows. Scoped to this section so every other use is untouched. */
#panel-size-cards .section-heading {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 12px;
  margin-bottom: clamp(32px, 4vw, 52px);
}

#panel-size-cards .section-heading .eyebrow {
  margin-bottom: 0;
  font-size: 0.95rem;
  letter-spacing: 0.14em;
}

#panel-size-cards .section-heading h2 {
  max-width: none;
  font-size: clamp(2rem, 3.6vw, 3rem);
}

#panel-size-cards .peripheral-heading-copy {
  max-width: 60ch;
  margin: 0 auto;
  font-size: 1.12rem;
  line-height: 1.7;
}

.panel-size-row-grid {
  display: grid;
  gap: clamp(28px, 4vw, 56px);
  max-width: 1800px;
  margin: 0 auto;
}

.panel-size-row {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(24px, 4vw, 64px);
  align-items: center;
  width: 100%;
  padding: 0;
  text-align: left;
  background: none;
  border: 0;
  cursor: pointer;
  font: inherit;
  color: inherit;
}

.panel-size-row-media {
  display: block;
  overflow: hidden;
  border-radius: 18px;
  background: var(--paper);
  box-shadow: var(--shadow);
  transition: box-shadow 200ms ease, transform 200ms ease;
}

.panel-size-row-media img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
}

.panel-size-row:hover .panel-size-row-media,
.panel-size-row:focus-visible .panel-size-row-media {
  transform: translateY(-4px);
  box-shadow: 0 26px 54px rgba(20, 32, 29, 0.22);
}

.panel-size-row:focus-visible {
  outline: 3px solid rgba(3, 84, 127, 0.35);
  outline-offset: 6px;
  border-radius: 18px;
}

.panel-size-row-copy {
  display: block;
}

.panel-size-row-title {
  display: block;
  margin-bottom: 16px;
  color: var(--ink);
  font-size: clamp(1.6rem, 2.6vw, 2.4rem);
  font-weight: 800;
  line-height: 1.15;
}

.panel-size-row-text {
  display: block;
  max-width: 46ch;
  color: var(--muted);
  font-size: 1.02rem;
  line-height: 1.7;
}

.panel-size-row-meta {
  display: block;
  margin-top: 14px;
  color: var(--accent-dark);
  font-size: 0.9rem;
  font-weight: 700;
}

.panel-size-row-cue {
  display: inline-block;
  margin-top: 18px;
  color: var(--accent-dark);
  font-weight: 750;
}

/* Alternating rows: image left on odd rows, right on even ones.
   Done with grid-column rather than `direction` or flex `row-reverse` so
   the DOM order is untouched -- screen readers and keyboard tabbing still
   hit the image then the copy on every row, regardless of which side the
   image is painted. */
.panel-size-row:nth-child(even) .panel-size-row-media {
  grid-column: 2;
  grid-row: 1;
}

.panel-size-row:nth-child(even) .panel-size-row-copy {
  grid-column: 1;
  grid-row: 1;
}

/* The wider track needs to follow the image across, otherwise the copy
   would get the roomier column on flipped rows. */
.panel-size-row:nth-child(even) {
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
}

/* Selected size -- a restrained accent, since these read as content rows
   rather than form controls. */
.panel-size-row.selected .panel-size-row-media {
  box-shadow: 0 0 0 3px var(--accent-dark), 0 22px 46px rgba(3, 84, 127, 0.24);
}

.panel-size-row.selected .panel-size-row-meta::after {
  content: " · selected";
}

/* Stacked: copy below the image, matching the brief. */
@media (max-width: 900px) {
  .panel-size-row,
  .panel-size-row:nth-child(even) {
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
  }

  /* The alternation has to be unwound explicitly. Left as-is, the even
     rows' `grid-column: 2` would generate an implicit second column in a
     one-column grid and the copy would sit beside a phantom track instead
     of under the image. `auto` returns them to normal flow order. */
  .panel-size-row:nth-child(even) .panel-size-row-media,
  .panel-size-row:nth-child(even) .panel-size-row-copy {
    grid-column: auto;
    grid-row: auto;
  }

  .panel-size-row-text {
    max-width: none;
  }
}

/* ===========================================================================
   RESPONSIVE PASS -- collapse two-column layouts (<=900px)
   ---------------------------------------------------------------------------
   Root cause of the sideways-scrolling and cut-off content reported on
   phones: most of these grids declare a second column of
   minmax(320px, ...) (360px on .aio-hero). A grid track with a 320px
   minimum cannot shrink below 320px, so once you add the gap and the first
   column the row demands ~460-500px MINIMUM -- wider than any phone. The
   page then overflows horizontally and the right-hand column is pushed off
   screen, which is why content looked "too big" and partly invisible.

   Collapsing to a single track removes the floor entirely. Done at 900px
   rather than 720px because two columns are already uncomfortably cramped
   on a small tablet.

   Everything here is inside a max-width query, so desktop is untouched.
   ========================================================================= */
@media (max-width: 900px) {
  .hero,
  .category-layout,
  .summary-panel,
  .split-band,
  .spec-band,
  .aio-hero,
  .aio-showcase,
  .aio-builder-grid,
  .aio-series-card,
  .peripheral-compare-section,
  .peripheral-benefits,
  .quick-quote-section,
  .warranty-check-details,
  .keyboard-detail-card,
  .monitor-detail-card,
  .mouse-detail-card,
  .monitor-overview-card,
  .mouse-overview-card,
  .workstation-specs-section .aio-spec-grid,
  .solutions-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Configurator option cards -- one per row reads far better than two
     cramped ones, and matches the signage grids already handled above. */
  .option-grid.two-col,
  .option-grid.three-col {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Media inside a collapsed hero no longer needs to hold a tall aspect;
     let it size to its own content instead of reserving desktop height. */
  .hero-media,
  .hero-media img {
    min-height: 0;
  }
}

/* Section padding is a large share of a phone's width -- clamp() minimums
   were set for desktop comfort. Trimming them gives content noticeably more
   room without changing anything above this breakpoint. */
@media (max-width: 620px) {
  .section,
  .category-hero {
    padding-left: 16px;
    padding-right: 16px;
  }

  .hero {
    padding-left: 16px;
    padding-right: 16px;
  }

  /* Cards and bands carry their own generous inner padding on top of the
     section padding, which compounds on a narrow screen. */
  .config-block,
  .configurator-shell,
  .summary-panel {
    padding-left: 16px;
    padding-right: 16px;
  }
}

/* ===========================================================================
   RESPONSIVE PASS -- hero heights and tap targets (<=900px)
   ========================================================================= */
@media (max-width: 900px) {
  /* Full-viewport heroes mean a phone user scrolls a whole screen before
     reaching any content. Cap them so the page starts paying off sooner.
     (.product-hero, .aio-hero, .monitor-hero etc. already reset at 640px;
     these are the ones with no override at all, plus a consistent cap for
     the rest.) */
  .hero,
  .product-hero,
  .desktop-hero,
  .aio-hero,
  .monitor-hero,
  .mouse-hero,
  .peripherals-hero,
  .workstation-hero,
  .solution-detail-hero {
    min-height: 0;
  }

  .peripherals-hero > img {
    min-height: 0;
    height: auto;
  }

  /* Touch targets. 44px is the long-standing iOS/Android minimum; these
     were sized for a mouse pointer and are awkward to hit with a thumb. */
  .choice-chip,
  .io-toggle,
  .search-button,
  .peripheral-card button {
    min-height: 44px;
  }

  .hero-carousel-arrow {
    width: 44px;
    height: 44px;
  }
}

/* ===========================================================================
   RESPONSIVE PASS -- "What We Supply, Who We Serve" (<=780px)
   ---------------------------------------------------------------------------
   Overlap fix. At this breakpoint .industries-panel becomes a column, but
   .industries-photo/.industries-copy keep `flex: 1 1 0` from the desktop
   rule -- and in a column container that `0` is a HEIGHT basis. On top of
   that, .industries-copy is given `min-height: 0`, which switches off the
   automatic minimum size that would otherwise stop a flex item shrinking
   below its content. Zero basis + no minimum = zero height, so the copy
   rendered on top of the following section ("Our Working Process").

   .industries-photo only escaped because it has an explicit height.

   Same underlying mistake as the About collage above: `flex: 1 1 0` is a
   row-direction idiom and doesn't survive the switch to column.
   ========================================================================= */
@media (max-width: 780px) {
  .industries-photo,
  .industries-copy {
    flex: 0 0 auto;
    width: 100%;
    min-width: 0;
  }

  /* Back to content height -- the 0 above was only there to cancel the
     desktop 460px, but it also removed the collapse protection. */
  .industries-copy {
    min-height: auto;
  }

  /* Photo scales with the screen rather than a fixed 320px. */
  .industries-photo {
    height: auto;
    aspect-ratio: 4 / 3;
    min-height: 220px;
  }

  /* Tabs stacked one per row -- four pills wrapping into an uneven 2x2
     block is hard to scan and gives small tap targets. */
  .industries-tabs {
    flex-direction: column;
    align-items: stretch;
  }

  .industries-tab {
    width: 100%;
    min-height: 48px;
    text-align: center;
  }
}

/* Same row-idiom-in-a-column situation as the two above, though this one
   isn't visibly broken: .hero-highlight-card has no `min-height: 0`, so a
   flex item's automatic minimum size still holds it at content height.
   Normalised anyway so all three stacked layouts behave the same way and
   nobody has to rediscover the distinction later. */
@media (max-width: 780px) {
  .hero-highlight-card {
    flex: 0 0 auto;
    width: 100%;
  }
}

/* ===========================================================================
   RESPONSIVE PASS -- About collage photos (<=780px)
   ---------------------------------------------------------------------------
   On desktop the two photos share one fixed-height box, split 1.15fr / 1fr,
   with the slides absolutely positioned so they can crossfade. Carried onto
   a phone that box becomes short and wide, so each photo is cropped to a
   narrow letterbox strip -- the portrait product shots suffer worst.

   Here the box gives up its fixed height and the active slide rejoins the
   normal flow, so the two photos simply stack at their own natural
   proportions with nothing cropped. Only the active slide is displayed, so
   about-collage.js can keep cycling them as it does now (it swaps the
   .is-active class; it just cross-fades on desktop and swaps instantly
   here).
   ========================================================================= */
@media (max-width: 780px) {
  .about-collage-photos {
    aspect-ratio: auto;
    height: auto;
    min-height: 0;
    overflow: visible;
    box-shadow: none;
  }

  .about-collage-slide {
    position: static;
    display: none;
    grid-template-rows: auto;
    gap: 12px;
    opacity: 1;
    transform: none;
  }

  .about-collage-slide.is-active {
    display: grid;
  }

  /* .is-prev is only meaningful for the outgoing crossfade. */
  .about-collage-slide.is-prev {
    display: none;
  }

  /* Radius moves from the shared box onto each photo now they're separate. */
  .about-collage-photo {
    height: auto;
    border-radius: 14px;
    overflow: hidden;
    box-shadow: var(--shadow);
  }

  /* height:100% + object-fit:cover is what forced the crop; natural height
     lets each image keep its own aspect ratio. */
  .about-collage-photo img {
    height: auto;
    aspect-ratio: auto;
    object-fit: contain;
  }
}

/* ===========================================================================
   Product-line gating for /product/configure/
   ---------------------------------------------------------------------------
   One page serves every product line, so the Interactive Panel and Digital
   Signage content blocks both live in the markup. configure.js tags <body>
   with .line-panel / .line-signage / .line-pc once the line loads, and these
   rules reveal only the matching block.

   (Restored: an earlier block-replacement in this file accidentally removed
   these along with the old size-card rules, which left BOTH blocks hidden on
   every line.)
   ========================================================================= */
.panel-only,
.signage-only {
  display: none;
}

body.line-panel .panel-only,
body.line-signage .signage-only {
  display: block;
}

/* Footnote under the signage standee comparison table (wall-mount sizes). */
.signage-table-note {
  margin: 14px 0 0;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.55;
}

/* ===========================================================================
   Digital Signage line -- configurator hero
   ---------------------------------------------------------------------------
   Mirrors the Interactive Panel hero above, gated on body.line-signage so
   the panel and PC lines keep their own hero.

   The standee sits at ~58% across, with clean wall to its left, so the copy
   column and the white veil both clear well before it -- the product itself
   is never blurred or washed out.
   ========================================================================= */
body.line-signage .category-hero {
  position: relative;
  display: flex;
  align-items: center;
  /* Section takes the photo's own 1672x941 proportions, so `cover` has
     nothing to crop -- the full frame is always visible, ceiling to floor.
     aspect-ratio is a preferred size, not a cap: if the copy ever needs
     more room than this (very narrow window, large text) the box still
     grows rather than clipping. */
  aspect-ratio: 1672 / 941;
  min-height: 0;
  padding: clamp(32px, 6vw, 80px) clamp(18px, 5vw, 72px);
  overflow: hidden;
  background-color: #fff;
  background-image: url("assets/signage-hero-standee.webp");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: right center;
}

body.line-signage .category-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Clears at 56%: the copy column now ends around 53% on mid-size screens
     (1280px and below), and the standee doesn't begin until 58% -- so this
     covers the text everywhere without touching the product. */
  background: linear-gradient(
    to right,
    rgba(255, 255, 255, 0.82) 0%,
    rgba(255, 255, 255, 0.78) 28%,
    rgba(255, 255, 255, 0.5) 42%,
    rgba(255, 255, 255, 0.2) 50%,
    rgba(255, 255, 255, 0) 56%
  );
}

/* The gradient-masked backdrop-filter frosting that used to sit here has
   been removed -- it softened the photo across the whole left half and the
   falloff was still faintly visible over the standee. The ::before gradient
   above carries the copy's legibility on its own, and the photo now stays
   sharp everywhere. */

body.line-signage .category-layout {
  position: relative;
  z-index: 2;
  display: block;
  max-width: 1800px;
  width: 100%;
  overflow: visible;
}

/* Wider column and larger type -- the section is now as tall as the photo
   (see aspect-ratio above), so the previous ~405px column of small text
   left most of the left-hand side empty. The standee starts at ~58% and the
   veil clears by 52%, so 620px still finishes well before either. */
body.line-signage .category-layout > div {
  width: min(620px, 48%);
  text-align: center;
}

body.line-signage #hero-image {
  display: none;
}

body.line-signage .category-layout h2 {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  font-size: clamp(1.9rem, 3.2vw, 3rem);
  line-height: 1.12;
}

body.line-signage .category-layout p:not(.eyebrow) {
  max-width: 42ch;
  margin: 18px auto 0;
  color: #3d4b5d;
  font-size: clamp(1.05rem, 1.25vw, 1.25rem);
  line-height: 1.7;
}

body.line-signage .category-layout .hero-actions {
  margin-top: 30px;
}

body.line-signage .category-layout .button {
  min-height: 56px;
  padding: 15px 30px;
  font-size: 1.08rem;
}

body.line-signage .category-layout .hero-actions {
  justify-content: center;
}


/* Mid widths (tablet / narrow window): the copy and the standee still share
   the frame -- the text just scales down with it rather than the veil going
   solid and painting the product out.
   The hero keeps the photo's own aspect ratio, so there's no horizontal
   crop at any width: the standee stays at ~58% across and the desktop
   gradient (clearing at 56%) still lines up correctly. */
@media (max-width: 900px) {
  body.line-signage .category-layout > div {
    width: min(360px, 48%);
  }

  body.line-signage .category-layout h2 {
    font-size: clamp(1.15rem, 3.1vw, 1.9rem);
  }

  body.line-signage .category-layout p:not(.eyebrow) {
    max-width: 34ch;
    margin-top: 10px;
    font-size: clamp(0.82rem, 1.7vw, 1rem);
    line-height: 1.55;
  }

  body.line-signage .category-layout .hero-actions {
    margin-top: 16px;
  }

  body.line-signage .category-layout .button {
    min-height: 42px;
    padding: 10px 18px;
    font-size: 0.9rem;
  }
}

/* Phones. The near-solid veil and full-width copy that used to live here
   were needed while the hero still carried a paragraph; with the copy cut
   back to the product name and CTA it stays in the left column instead and
   the desktop gradient is kept. See the block further down that sets the
   narrower column -- it's the one in force at these widths now. */
@media (max-width: 620px) {
  body.line-signage .category-layout h2,
  body.line-signage .category-layout p:not(.eyebrow) {
    max-width: none;
  }
}

/* Portrait media variant of the shared feature row (.panel-size-row-*).
   The panel size rows use landscape 16/10 photos; the signage standee and
   wall-mount renders are portrait (~0.75-0.80:1), so a 16/10 cover crop
   would slice the top and bottom off the product itself. 4/5 keeps them
   whole with only a sliver trimmed at the sides. */
.panel-size-row-media.is-portrait img {
  aspect-ratio: 4 / 5;
}

/* Portrait art is much taller than wide, so give the copy the roomier
   track on these rows rather than the image. */
#signage-type-rows .panel-size-row {
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  align-items: center;
}

#signage-type-rows .panel-size-row:nth-child(even) {
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
}

/* Centred heading, matching the panel size section. */
#signage-type-rows .section-heading {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 12px;
  margin-bottom: clamp(32px, 4vw, 52px);
}

#signage-type-rows .section-heading .eyebrow {
  margin-bottom: 0;
  font-size: clamp(1rem, 1.15vw, 1.2rem);
  letter-spacing: 0.16em;
}

#signage-type-rows .section-heading h2 {
  max-width: none;
  font-size: clamp(2.4rem, 5.2vw, 4.4rem);
  line-height: 1.08;
}

/* The 60ch cap was breaking this single sentence onto a second line with
   one orphaned word. Uncapped it sits on one line on desktop and wraps
   naturally only when the screen is genuinely too narrow. */
#signage-type-rows .peripheral-heading-copy {
  max-width: none;
  margin: 0 auto;
  font-size: clamp(1.15rem, 1.45vw, 1.45rem);
  line-height: 1.6;
}

/* These rows are links, not buttons -- keep the site's link colour from
   overriding the row's own typography. */
#signage-type-rows .panel-size-row {
  color: inherit;
  text-decoration: none;
}

@media (max-width: 900px) {
  #signage-type-rows .panel-size-row,
  #signage-type-rows .panel-size-row:nth-child(even) {
    grid-template-columns: minmax(0, 1fr);
  }

  /* A full-height portrait image is overwhelming on a phone; crop to a
     gentler ratio once stacked. */
  .panel-size-row-media.is-portrait img {
    aspect-ratio: 3 / 4;
  }
}

/* ===========================================================================
   Panel / Signage content sections -- centred headings
   ---------------------------------------------------------------------------
   Centres the headings of the sections below the configurator (Premium
   Features, Technical Specifications Overview, Why Choose ...).

   Scoped to .panel-only / .signage-only deliberately: these sections reuse
   the monitor page's .monitor-* classes, and that page still wants its
   original left-aligned headings.
   ========================================================================= */
.panel-only .section-heading,
.signage-only .section-heading {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 10px;
  margin-bottom: clamp(28px, 3.5vw, 44px);
}

.panel-only .section-heading .eyebrow,
.signage-only .section-heading .eyebrow {
  margin-bottom: 0;
  font-size: clamp(0.95rem, 1.1vw, 1.1rem);
  letter-spacing: 0.15em;
}

.panel-only .section-heading h2,
.signage-only .section-heading h2,
.panel-only > section > h2,
.signage-only > section > h2 {
  max-width: none;
  text-align: center;
  font-size: clamp(1.9rem, 3.4vw, 2.9rem);
  line-height: 1.12;
}

/* The spec-overview and why-choose sections use a bare <h2> rather than a
   .section-heading wrapper, so they need centring in their own right. */
.panel-only .monitor-spec-overview > h2,
.panel-only .monitor-why-section > h2,
.signage-only .monitor-spec-overview > h2,
.signage-only .monitor-why-section > h2 {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}

/* Larger copy on the signage format rows -- the portrait art is tall, so
   the text column had a lot of vertical room going spare next to it.
   Scoped to this section; the panel size rows keep their own scale. */
#signage-type-rows .panel-size-row-title {
  margin-bottom: 20px;
  font-size: clamp(1.9rem, 3.2vw, 3rem);
}

#signage-type-rows .panel-size-row-text {
  max-width: 52ch;
  font-size: clamp(1.08rem, 1.35vw, 1.35rem);
  line-height: 1.68;
}

#signage-type-rows .panel-size-row-meta {
  margin-top: 20px;
  font-size: clamp(0.95rem, 1.05vw, 1.05rem);
}

#signage-type-rows .panel-size-row-cue {
  margin-top: 22px;
  font-size: clamp(1rem, 1.15vw, 1.15rem);
}

@media (max-width: 900px) {
  #signage-type-rows .panel-size-row-title {
    margin-bottom: 14px;
  }

  #signage-type-rows .panel-size-row-text {
    max-width: none;
  }
}

/* Copy centred within its own column on the signage format rows (the row
   itself stays vertically centred via align-items above, so the block sits
   in the middle of its half both ways). */
#signage-type-rows .panel-size-row-copy {
  text-align: center;
}

#signage-type-rows .panel-size-row-text {
  margin-left: auto;
  margin-right: auto;
}

/* ===========================================================================
   Panel size rows -- brought in line with the signage format rows
   ---------------------------------------------------------------------------
   Same enlarged, centred treatment applied above to #signage-type-rows, so
   the two sections read as one system rather than two different scales.
   Appended after the earlier #panel-size-cards rules so these win on ties.

   The track ratio is deliberately NOT copied across: the signage art is
   portrait and gets the narrower column, while these panel photos are
   landscape and keep the roomier one.
   ========================================================================= */
#panel-size-cards .section-heading .eyebrow {
  font-size: clamp(1rem, 1.15vw, 1.2rem);
  letter-spacing: 0.16em;
}

#panel-size-cards .section-heading h2 {
  font-size: clamp(2.4rem, 5.2vw, 4.4rem);
  line-height: 1.08;
}

#panel-size-cards .peripheral-heading-copy {
  max-width: none;
  font-size: clamp(1.15rem, 1.45vw, 1.45rem);
  line-height: 1.6;
}

#panel-size-cards .panel-size-row-title {
  margin-bottom: 20px;
  font-size: clamp(1.9rem, 3.2vw, 3rem);
}

#panel-size-cards .panel-size-row-text {
  max-width: 52ch;
  margin-left: auto;
  margin-right: auto;
  font-size: clamp(1.08rem, 1.35vw, 1.35rem);
  line-height: 1.68;
}

#panel-size-cards .panel-size-row-meta {
  margin-top: 20px;
  font-size: clamp(0.95rem, 1.05vw, 1.05rem);
}

#panel-size-cards .panel-size-row-cue {
  margin-top: 22px;
  font-size: clamp(1rem, 1.15vw, 1.15rem);
}

#panel-size-cards .panel-size-row-copy {
  text-align: center;
}

@media (max-width: 900px) {
  #panel-size-cards .panel-size-row-title {
    margin-bottom: 14px;
  }

  #panel-size-cards .panel-size-row-text {
    max-width: none;
  }
}

/* ===========================================================================
   Monitor page -- centred section headings
   ---------------------------------------------------------------------------
   Same treatment as the panel/signage content sections: headings stacked
   and centred, at a consistent size.

   Scoped to main.monitor-page so it can't reach the same .monitor-* classes
   where they're reused inside .panel-only / .signage-only on the shared
   configurator page (those already have their own centred rules).
   The hero contains no headings, so it is untouched by definition.
   ========================================================================= */
.monitor-page .section-heading {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 10px;
  margin-bottom: clamp(28px, 3.5vw, 44px);
}

.monitor-page .section-heading .eyebrow {
  margin-bottom: 0;
  font-size: clamp(0.95rem, 1.1vw, 1.1rem);
  letter-spacing: 0.15em;
}

.monitor-page .section-heading h2,
.monitor-page .monitor-spec-overview > h2,
.monitor-page .monitor-why-section > h2 {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  font-size: clamp(1.9rem, 3.4vw, 2.9rem);
  line-height: 1.12;
}

/* The intro line beside each heading becomes a centred subtitle once the
   heading block is stacked. */
.monitor-page .peripheral-heading-copy {
  max-width: 62ch;
  margin: 0 auto;
  text-align: center;
}

/* ===========================================================================
   Monitor picker -- feature rows
   ---------------------------------------------------------------------------
   Same enlarged, centred row treatment as the panel and signage sections.
   Reuses .panel-size-row-* so all three sections share one implementation.
   ========================================================================= */
#monitor-products .panel-size-row-title {
  margin-bottom: 20px;
  font-size: clamp(1.9rem, 3.2vw, 3rem);
}

#monitor-products .panel-size-row-text {
  max-width: 52ch;
  margin-left: auto;
  margin-right: auto;
  font-size: clamp(1.08rem, 1.35vw, 1.35rem);
  line-height: 1.68;
}

/* The price. Kept as <strong> because the live-pricing script rewrites it
   by tag name, not class. */
#monitor-products .panel-size-row-price {
  display: block;
  margin-top: 22px;
  color: var(--accent-dark);
  font-size: clamp(1.5rem, 2.2vw, 2rem);
  font-weight: 800;
}

#monitor-products .panel-size-row-meta {
  margin-top: 10px;
  font-size: clamp(0.95rem, 1.05vw, 1.05rem);
}

#monitor-products .panel-size-row-cue {
  margin-top: 20px;
  font-size: clamp(1rem, 1.15vw, 1.15rem);
}

#monitor-products .panel-size-row-copy {
  text-align: center;
}

@media (max-width: 900px) {
  #monitor-products .panel-size-row-title {
    margin-bottom: 14px;
  }

  #monitor-products .panel-size-row-text {
    max-width: none;
  }
}

/* The sticky header is 88px tall, so an element scrolled to via
   scrollIntoView / an #anchor would have its top 88px hidden behind it.
   scroll-margin-top reserves that space plus a little breathing room. */
#monitor-detail {
  scroll-margin-top: 108px;
}

/* The detail card was a two-column grid (copy | photo). With the photo
   removed the copy takes the full width, otherwise it would sit in a
   half-width column with an empty track beside it. */
#monitor-detail .monitor-detail-card {
  grid-template-columns: minmax(0, 1fr);
}

/* Monitor row images shown whole -- no crop.
   The shared row frame is a fixed 16/10 with object-fit:cover, which was
   slicing the top and bottom off these product shots (the 27-inch photo is
   1.11:1, so ~30% of it was being cut). Forcing them into that frame with
   `contain` instead would have left 30% empty bars, so the frame simply
   gives up its fixed ratio here: each image fills the column width and
   takes its own natural height. Rows differ slightly in image height as a
   result, which reads fine since each row is its own band. */
#monitor-products .panel-size-row-media img {
  aspect-ratio: auto;
  height: auto;
  object-fit: contain;
}

/* Light backing so any transparent edge blends with the product shots'
   own white backgrounds rather than showing the page tint. */
#monitor-products .panel-size-row-media {
  background: #ffffff;
}

/* Monitor picker heading -- same enlarged scale as the panel and signage
   size sections, so the three picker sections match. The intro line loses
   its 62ch cap so it spans the width instead of wrapping early onto a
   second line. */
#monitor-products .section-heading .eyebrow {
  font-size: clamp(1rem, 1.15vw, 1.2rem);
  letter-spacing: 0.16em;
}

#monitor-products .section-heading h2 {
  font-size: clamp(2.4rem, 5.2vw, 4.4rem);
  line-height: 1.08;
}

#monitor-products .peripheral-heading-copy {
  max-width: none;
  font-size: clamp(1.15rem, 1.45vw, 1.45rem);
  line-height: 1.6;
}

/* Keyboard hero -- copy column sized so it always clears the keyboard.
   The keyboard starts at 55.9% of the photo and the veil clears at 54%, so
   the copy has to finish before that. A flat 640px was ~83% of a 770px
   window, which is exactly why the text ran over the keys. */
.keyboard-hero-content {
  width: min(640px, 46%);
}

@media (max-width: 900px) {
  /* Copy and keyboard still share the frame; the text scales down with it
     rather than the overlay going solid and hiding the product. */
  .keyboard-hero-content {
    width: min(340px, 44%);
  }

  .keyboard-hero-content h1 {
    font-size: clamp(1.05rem, 2.4vw, 1.6rem);
  }

  .keyboard-hero-content > p:not(.eyebrow) {
    max-width: 34ch;
    margin-top: 8px;
    font-size: clamp(0.78rem, 1.5vw, 0.95rem);
    line-height: 1.5;
  }

  .keyboard-hero .hero-actions {
    margin-top: 14px;
    gap: 8px;
  }

  .keyboard-hero .button {
    min-height: 40px;
    padding: 9px 14px;
    font-size: 0.84rem;
  }
}

/* Phones: no room beside the keyboard, so the overlay goes near-solid and
   the copy takes the full width. */
@media (max-width: 620px) {
  .keyboard-hero-overlay {
    background: rgba(227, 225, 233, 0.9);
  }

  .keyboard-hero-content {
    width: 100%;
  }

  .keyboard-hero-content > p:not(.eyebrow) {
    max-width: none;
  }
}

/* ===========================================================================
   Keyboard page -- centred section headings
   ---------------------------------------------------------------------------
   Same treatment as the monitor / panel / signage sections.

   Targets .section-heading only, NOT every h2 on the page: the detail card
   carries a bare <h2> for the product title ("Litset Wireless Keyboard")
   which belongs to that two-column card and should stay left-aligned.
   The hero's <h1> sits in .keyboard-hero-content, so it's untouched too.
   ========================================================================= */
.keyboard-page .section-heading {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 10px;
  margin-bottom: clamp(28px, 3.5vw, 44px);
}

.keyboard-page .section-heading .eyebrow {
  margin-bottom: 0;
  font-size: clamp(1rem, 1.15vw, 1.2rem);
  letter-spacing: 0.16em;
}

.keyboard-page .section-heading h2 {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  font-size: clamp(2.4rem, 5.2vw, 4.4rem);
  line-height: 1.08;
}

.keyboard-page .peripheral-heading-copy {
  max-width: none;
  margin: 0 auto;
  text-align: center;
  font-size: clamp(1.15rem, 1.45vw, 1.45rem);
  line-height: 1.6;
}

/* Mouse hero -- copy column sized to clear the product (glow ring starts
   at ~48%, veil clears there too). A flat 640px was most of a narrow
   window, which put the text over the mouse. */
.mouse-hero-content {
  width: min(640px, 40%);
}

@media (max-width: 900px) {
  .mouse-hero-content {
    width: min(320px, 40%);
  }

  .mouse-hero-content h1 {
    font-size: clamp(1.05rem, 2.4vw, 1.6rem);
  }

  .mouse-hero-content > p:not(.eyebrow) {
    max-width: 32ch;
    margin-top: 8px;
    font-size: clamp(0.78rem, 1.5vw, 0.95rem);
    line-height: 1.5;
  }

  .mouse-hero .hero-actions {
    margin-top: 14px;
    gap: 8px;
  }

  .mouse-hero .button {
    min-height: 40px;
    padding: 9px 14px;
    font-size: 0.84rem;
  }
}

@media (max-width: 620px) {
  .mouse-hero-overlay {
    background: rgba(169, 167, 180, 0.9);
  }

  .mouse-hero-content {
    width: 100%;
  }

  .mouse-hero-content > p:not(.eyebrow) {
    max-width: none;
  }
}

/* ===========================================================================
   Mouse page -- centred section headings
   ---------------------------------------------------------------------------
   Matches the monitor / keyboard / panel / signage pages. Targets
   .section-heading only: the detail card's bare <h2> is the product title
   and stays left-aligned, and the hero <h1> lives in .mouse-hero-content.
   ========================================================================= */
.mouse-page .section-heading {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 10px;
  margin-bottom: clamp(28px, 3.5vw, 44px);
}

.mouse-page .section-heading .eyebrow {
  margin-bottom: 0;
  font-size: clamp(1rem, 1.15vw, 1.2rem);
  letter-spacing: 0.16em;
}

.mouse-page .section-heading h2 {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  font-size: clamp(2.4rem, 5.2vw, 4.4rem);
  line-height: 1.08;
}

.mouse-page .peripheral-heading-copy {
  max-width: none;
  margin: 0 auto;
  text-align: center;
  font-size: clamp(1.15rem, 1.45vw, 1.45rem);
  line-height: 1.6;
}

/* The spec-overview and why-choose sections use a bare <h2> of their own
   (mirrors the monitor page's handling). */
.mouse-page .mouse-spec-overview > h2,
.mouse-page .mouse-why-section > h2 {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  font-size: clamp(1.9rem, 3.4vw, 2.9rem);
  line-height: 1.12;
}

/* ===========================================================================
   Desktop PCs page -- centred section headings
   ---------------------------------------------------------------------------
   Matches the monitor / keyboard / mouse / panel / signage pages.
   The page had no wrapper class, so `.desktop-page` was added to its <main>
   purely as a scoping hook -- these generic .section / .section-heading
   classes are used site-wide and must not change elsewhere.
   ========================================================================= */
.desktop-page .section-heading {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 10px;
  margin-bottom: clamp(28px, 3.5vw, 44px);
}

.desktop-page .section-heading .eyebrow {
  margin-bottom: 0;
  font-size: clamp(1rem, 1.15vw, 1.2rem);
  letter-spacing: 0.16em;
}

.desktop-page .section-heading h2 {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  font-size: clamp(2.4rem, 5.2vw, 4.4rem);
  line-height: 1.08;
}

.desktop-page .peripheral-heading-copy,
.desktop-page .section-heading > p:not(.eyebrow) {
  max-width: none;
  margin: 0 auto;
  text-align: center;
  font-size: clamp(1.15rem, 1.45vw, 1.45rem);
  line-height: 1.6;
}

/* .spec-band is a two-column band -- its heading sits in the narrow left
   column beside the spec grid, so centring it there reads as a mistake
   rather than a choice. Left as it was. */
.desktop-page .spec-band .section-heading {
  align-items: start;
  text-align: left;
}

.desktop-page .spec-band .section-heading h2 {
  margin-left: 0;
  text-align: left;
  font-size: clamp(2rem, 4vw, 3.5rem);
}

/* ===========================================================================
   Hero height floor -- applies ONLY to the heroes that use aspect-ratio
   ---------------------------------------------------------------------------
   `aspect-ratio` sets a *preferred* height. Paired with `min-height: 0` the
   box stays locked at width/ratio, so on a narrow screen -- where the box
   shrinks but the text doesn't -- the copy overflows and is clipped by the
   hero's `overflow: hidden`. That's what was cutting off the desktop hero
   heading.

   fit-content raises the floor to the content's own height, so the box
   grows when the copy needs it and honours the ratio whenever it fits.

   Listed explicitly rather than applied to every `min-height: 0` in the
   file: most of those cancel a large fixed min-height (e.g.
   .monitor-hero-video, .hero-media img) and would be broken by a
   content-based floor.
   ========================================================================= */
.desktop-hero,
.keyboard-hero,
.mouse-hero,
body.line-panel .category-hero,
body.line-signage .category-hero {
  min-height: fit-content;
}

/* ===========================================================================
   Heroes: release the aspect ratio on small screens
   ---------------------------------------------------------------------------
   Above ~700px the copy fits inside the ratio-derived box comfortably.
   Below that it doesn't -- at 390px the desktop hero's copy needs ~317px
   while the ratio box is only 218px -- so the text overflowed and was cut
   off by `overflow: hidden`.

   `min-height: fit-content` was meant to cover this but doesn't hold here
   (the heroes are grid/flex containers with padding, and the ratio keeps
   winning), so the ratio is simply dropped at this breakpoint: height goes
   back to being driven by the content, and the background image covers
   whatever box results. Cropping the image a little is a far better outcome
   than clipping the headline.
   ========================================================================= */
@media (max-width: 980px) {
  .desktop-hero,
  .keyboard-hero,
  .mouse-hero,
  body.line-panel .category-hero,
  body.line-signage .category-hero {
    aspect-ratio: auto;
    min-height: 0;
    padding-top: clamp(28px, 6vw, 64px);
    padding-bottom: clamp(28px, 6vw, 64px);
  }
}

/* ===========================================================================
   Signage hero -- stop the standee being cropped on small screens
   ---------------------------------------------------------------------------
   Releasing the ratio above fixes the clipped-headline problem but leaves
   the height driven purely by the copy, which is much shorter than the
   photo is tall: at 570px wide the box came out ~245px against the 321px
   the 1672x941 image needs, so `cover` sliced roughly a quarter off the
   standee -- top and bottom.

   A min-height instead of a ratio keeps both properties: the box can still
   grow past it when the copy needs more room (so nothing is ever clipped),
   but it never falls below the photo's own proportions, so there's nothing
   to crop.

   55vw rather than the exact 56.28vw (941/1672) because `vw` includes the
   scrollbar while the hero doesn't -- the small undershoot keeps the box
   marginally *wider* than the image, which means `cover` scales to width
   and any residual crop is a ~2% vertical trim rather than a horizontal
   one that would slide the standee out from under the gradient stops. */
@media (max-width: 980px) {
  body.line-signage .category-hero {
    height: auto;
    min-height: 55vw;
  }
}

/* ===========================================================================
   Signage hero on phones -- cut the copy down instead of moving it
   ---------------------------------------------------------------------------
   Down to 620px the copy sits in its own column to the left of the standee
   and the two never meet. Below that there's no width left for a column, so
   the copy has to go over the photo -- and a full headline + paragraph +
   button needed so much veil to stay legible that it washed the standee
   out completely.

   So the hero drops to just the product name and the CTA. Three words and a
   button are small enough to stay in the left column at these widths rather
   than being laid over the photo, so the veil doesn't go solid here at all
   -- the desktop gradient (clear by 56%) carries straight through and the
   standee, which starts at 58%, is never covered. The description isn't
   lost: the same text runs directly below in the configurator intro.

   The column is capped at 48% so that its right edge -- padding included --
   lands around 53%, comfortably inside where the gradient clears.
   ========================================================================= */
@media (max-width: 620px) {
  body.line-signage .category-layout > div {
    width: min(300px, 48%);
  }

  body.line-signage .category-layout p:not(.eyebrow) {
    display: none;
  }

  /* Bigger than the ≤900 sizing (which was shrunk to fit a whole paragraph
     beside the standee) but still sized to the column: at 390px the column
     is ~187px and "Signage" -- the longest word -- has to fit on one line. */
  body.line-signage .category-layout h2 {
    font-size: clamp(1.25rem, 5vw, 1.8rem);
  }

  body.line-signage .category-layout .hero-actions {
    margin-top: 18px;
  }

  /* "Start Configuring" is a wide label for a ~173px column on a 360px
     phone, so the button is kept compact enough to sit inside it. */
  body.line-signage .category-layout .button {
    min-height: 44px;
    padding: 11px 15px;
    font-size: 0.85rem;
  }
}

/* Desktop hero scrim on small screens.
   The ≤980 overlay fades from fully transparent at the TOP down to dark at
   the bottom -- which worked while the hero was a tall viewport-height band
   with the copy sitting low in it. Now that the hero is sized by its
   content, the copy starts at the very top, exactly where that gradient has
   no coverage, so the headline was landing on the bare tower.
   A near-even dark scrim keeps the copy readable wherever it falls while
   still letting the cabinet show through. */
@media (max-width: 980px) {
  .desktop-hero-overlay {
    background: linear-gradient(
      180deg,
      rgba(8, 9, 12, 0.55) 0%,
      rgba(8, 9, 12, 0.62) 55%,
      rgba(8, 9, 12, 0.7) 100%
    );
  }
}

/* ===========================================================================
   Desktop hero on small screens -- match the keyboard/mouse pattern
   ---------------------------------------------------------------------------
   The keyboard and mouse heroes keep their copy in a narrow column at these
   widths (44% / 40%), so the product stays visible beside it. The desktop
   hero instead had `max-width: none`, letting the copy run the full width --
   which is why it sat on top of the tower rather than beside it.

   Same treatment here: the copy stays in a right-hand column clear of the
   tower (which occupies roughly 9%-42% of the frame), with the type scaled
   down to suit, and the overlay back to a horizontal gradient that darkens
   only the right-hand side instead of washing the whole image.
   ========================================================================= */
@media (max-width: 980px) {
  .desktop-hero-content {
    max-width: min(400px, 46%);
  }

  .desktop-hero-content h2 {
    font-size: clamp(1.05rem, 2.5vw, 1.7rem);
    line-height: 1.15;
  }

  .desktop-hero-content p {
    max-width: 34ch;
    margin-top: 8px;
    font-size: clamp(0.78rem, 1.5vw, 0.95rem);
    line-height: 1.5;
  }

  .desktop-hero .hero-actions {
    margin-top: 14px;
    gap: 8px;
  }

  .desktop-hero .button {
    min-height: 40px;
    padding: 9px 14px;
    font-size: 0.84rem;
  }

  /* Dark only on the right, clear across the tower on the left. */
  .desktop-hero-overlay {
    background: linear-gradient(
      270deg,
      rgba(8, 9, 12, 0.9) 0%,
      rgba(8, 9, 12, 0.8) 30%,
      rgba(8, 9, 12, 0.35) 45%,
      rgba(8, 9, 12, 0) 55%
    );
  }
}

@media (max-width: 620px) {
  /* Kept as a column rather than going full width. Centered text only reads
     as "centered on the right" if there's a right-hand column to center it
     in -- at full width it would just land in the middle of the screen,
     back over the tower. 68% leaves the cabinet clear on the left. */
  .desktop-hero-content {
    max-width: min(380px, 68%);
  }

  /* Was a flat rgba(8, 9, 12, 0.72) across the whole hero, which is what
     made the cabinet read as almost solid black on a phone -- an even scrim
     that heavy has to cover the tower to cover the text. With the paragraph
     gone (below) only the heading and buttons need backing, and those sit
     on the right, so the darkness can be weighted there and lifted off the
     tower entirely. */
  .desktop-hero-overlay {
    background: linear-gradient(
      270deg,
      rgba(8, 9, 12, 0.86) 0%,
      rgba(8, 9, 12, 0.66) 32%,
      rgba(8, 9, 12, 0.22) 58%,
      rgba(8, 9, 12, 0) 76%
    );
  }
}

/* The intro paragraph is dropped on phones. In a narrow column beside the
   tower it ran to four or five lines -- most of the hero's height -- and
   that bulk is what forced the heavy scrim above. The heading and the two
   buttons carry the section on their own at this size, and the Desktop
   Options section immediately below opens with its own heading and
   descriptions, so nothing is left unexplained.

   Note `display: none` also hides it from screen readers. That's the right
   call here (it's marketing copy that repeats the heading's point, not
   unique information), but worth knowing it isn't a purely visual change. */
@media (max-width: 720px) {
  .desktop-hero-content p {
    display: none;
  }
}

/* Keep the desktop hero copy on the right at narrow widths.
   An earlier ≤980 rule flips `justify-items: start`, which made sense when
   the copy went full width and the overlay was a top-to-bottom scrim. Now
   that the copy is back in a column beside the tower, `start` drops it onto
   the tower on the left -- the clear space is on the right. */
@media (max-width: 980px) {
  .desktop-hero {
    justify-items: end;
  }
}

/* ===========================================================================
   Desktop hero -- never crop the cabinet photo
   ---------------------------------------------------------------------------
   The shared "release the aspect ratio below 980px" rule further up gives
   this hero a content-driven height, and `cover` then trims the photo to
   whatever box that produces -- up to a third of it at the narrow end.

   The ratio is put back here, so the section is always exactly the photo's
   own 2200x1228 and there is nothing for `cover` to cut. That's only
   affordable now that the paragraph is hidden below 720px: measured at
   every width from 980px down to 360px, the heading and buttons clear the
   ratio-derived height with 8-195px to spare.

   `min-height: fit-content` is the safety net -- `aspect-ratio` is a
   preferred size, not a cap, so if the copy ever does outgrow the box (a
   longer headline, a larger default font) the section grows rather than
   clipping the text. Below 380px the padding and heading floor come down
   too, which is what buys the last of that clearance on a 320px screen.
   ========================================================================= */
@media (max-width: 980px) {
  .desktop-hero {
    aspect-ratio: 2200 / 1228;
    min-height: fit-content;
  }
}

/* ===========================================================================
   Desktop hero -- keep the copy inside the ratio box on small screens
   ---------------------------------------------------------------------------
   The heading carries hard <br> breaks, so it's meant to be three lines. But
   at these widths the copy column is only ~68% of the screen, and at the old
   1.5rem floor the longest line ("Reliable Litset desktops", 24 characters)
   no longer fits it -- so it wrapped to a fourth line. The hero's height is
   set by the photo's aspect ratio and doesn't grow with its contents, so
   that extra line pushed the second button out through `overflow: hidden`.

   Two constraints have to hold at once, and the heading size is solved
   against both:

     - horizontal: the longest line must fit the column, so
       font-size <= column / 12
     - vertical: three lines plus the stacked buttons must fit the
       ratio-derived height

   5.4vw satisfies the first at every width; the reduced padding and slightly
   shorter buttons below give the second enough room. Under 380px no font
   size satisfies both, so the ratio is released there and the height follows
   the content instead -- that crops the photo about 8% at the sides, which
   is nothing next to a clipped button.
   ========================================================================= */
@media (max-width: 620px) {
  .desktop-hero {
    padding-top: 20px;
    padding-bottom: 20px;
  }
}

@media (max-width: 420px) {
  .desktop-hero .button {
    min-height: 36px;
  }
}

@media (max-width: 380px) {
  .desktop-hero {
    aspect-ratio: auto;
    min-height: 0;
  }
}

/* Phones: the copy stays on the right, matching the 721-980 band, so the
   tower keeps the clear space on the left.

   `justify-items: end` on its own doesn't finish the job. It places the
   *block* at the right, but the block's own `text-align` and the auto
   margins on the h2 and paragraph decide where the text lands inside it --
   so alignment is set on the contents as well as the box. */
@media (max-width: 720px) {
  .desktop-hero {
    justify-items: end;
  }

  .desktop-hero-content {
    text-align: center;
  }

  .desktop-hero-content h2,
  .desktop-hero-content p {
    margin-left: auto;
    margin-right: auto;
  }

  .desktop-hero-content .hero-actions {
    justify-content: center;
  }
}

/* ===========================================================================
   Desktop options -- feature rows
   ---------------------------------------------------------------------------
   Same treatment as the panel / signage / monitor picker rows.
   ========================================================================= */
#desktop-options .panel-size-row-title {
  margin-bottom: 18px;
  font-size: clamp(1.9rem, 3.2vw, 3rem);
}

#desktop-options .panel-size-row-text {
  max-width: 52ch;
  margin-left: auto;
  margin-right: auto;
  font-size: clamp(1.08rem, 1.35vw, 1.35rem);
  line-height: 1.68;
}

#desktop-options .panel-size-row-copy {
  text-align: center;
}

#desktop-options .panel-size-row-copy .eyebrow {
  margin-bottom: 12px;
}

/* The bullet list stays LEFT-aligned inside a centred block. Centred
   bullets read badly -- the markers end up ragged down the middle -- so the
   list box is centred while its text is not. */
.panel-size-row-list {
  display: inline-block;
  max-width: 46ch;
  margin: 22px auto 0;
  padding-left: 1.15em;
  text-align: left;
  color: var(--muted);
  font-size: clamp(1rem, 1.2vw, 1.15rem);
  line-height: 1.75;
}

.panel-size-row-list li + li {
  margin-top: 6px;
}

@media (max-width: 900px) {
  #desktop-options .panel-size-row-title {
    margin-bottom: 12px;
  }

  #desktop-options .panel-size-row-text,
  .panel-size-row-list {
    max-width: none;
  }
}

/* This page titles its sections with <h3>, not <h2> -- so the earlier
   `.desktop-page .section-heading h2` rule never reached them and they
   stayed at the small default size while every other page's headings grew. */
.desktop-page .section-heading h3 {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  font-size: clamp(2.4rem, 5.2vw, 4.4rem);
  line-height: 1.08;
}

.desktop-page .spec-band .section-heading h3 {
  margin-left: 0;
  text-align: left;
  font-size: clamp(2rem, 4vw, 3.5rem);
}

/* ===========================================================================
   Picker/section headings -- steeper scaling in the mid range
   ---------------------------------------------------------------------------
   These headings were clamp(2.4rem, 5.2vw, 4.4rem). The vw term only
   overtakes the 2.4rem floor above ~740px, so on a narrow desktop window
   (e.g. 654px) they sat at the floor and read small next to the row copy,
   even though they hit the intended 70px on a wide monitor.

   7vw reaches the 4.4rem ceiling by ~1000px instead of ~1350px, so the
   mid range grows while the floor (small phones) and ceiling (large
   screens) are unchanged.
   Listed explicitly -- no bulk find/replace on this file.
   ========================================================================= */
.desktop-page .section-heading h2,
.desktop-page .section-heading h3,
.monitor-page .section-heading h2,
.keyboard-page .section-heading h2,
.mouse-page .section-heading h2,
#monitor-products .section-heading h2,
#panel-size-cards .section-heading h2,
#signage-type-rows .section-heading h2 {
  font-size: clamp(2.4rem, 7vw, 4.4rem);
}

/* The two-column spec band keeps its smaller, left-aligned heading. */
.desktop-page .spec-band .section-heading h2,
.desktop-page .spec-band .section-heading h3 {
  font-size: clamp(2rem, 4vw, 3.5rem);
}

/* Desktop page headings -- override the older ID-scoped 1.35rem rule.
   `#desktop-options .section-heading h3` (specificity 1-1-1) outranks
   `.desktop-page .section-heading h3` (0-2-1), so every attempt to size
   these via the page class was silently losing and they stayed at 1.35rem
   (~21px) while the monitor page's h2 grew to the full clamp.
   Matching the ID specificity here so they finally take the shared scale. */
#desktop-options .section-heading h3,
#pricing .section-heading h3,
.comparison-section .section-heading h2 {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  font-size: clamp(2.4rem, 7vw, 4.4rem);
  line-height: 1.08;
}

/* Desktop page heading balance: bigger eyebrow, slightly smaller title.
   Both need ID-level specificity -- `#desktop-options .section-heading
   .eyebrow` (1-2-0) was pinning the eyebrow to 0.92rem, the same trap the
   h3 hit. */
#desktop-options .section-heading .eyebrow,
#pricing .section-heading .eyebrow,
.comparison-section .section-heading .eyebrow {
  margin-bottom: 0;
  font-size: clamp(1.15rem, 1.7vw, 1.55rem);
  letter-spacing: 0.18em;
}

#desktop-options .section-heading h3,
#pricing .section-heading h3,
.comparison-section .section-heading h2 {
  font-size: clamp(2rem, 5.4vw, 3.4rem);
}

/* Desktop Strengths -- brought in line with the other section headings.
   Two changes are needed together:
   1. #desktop-strengths pins the heading/eyebrow at ID specificity (1.35rem
      / 0.92rem), same trap as #desktop-options -- overridden here.
   2. .spec-band is a two-column band (heading left, spec grid right), so a
      centred heading only makes sense once it stacks. The band becomes a
      single column on this page so the heading sits above the grid like
      every other section. */
#desktop-strengths {
  grid-template-columns: minmax(0, 1fr);
}

#desktop-strengths .section-heading {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 10px;
  margin-bottom: clamp(28px, 3.5vw, 44px);
}

#desktop-strengths .section-heading .eyebrow {
  margin-bottom: 0;
  font-size: clamp(1.15rem, 1.7vw, 1.55rem);
  letter-spacing: 0.18em;
}

#desktop-strengths .section-heading h2 {
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  font-size: clamp(2rem, 5.4vw, 3.4rem);
  line-height: 1.08;
}

/* ===========================================================================
   Solutions hero -- same treatment as the keyboard/mouse/desktop heroes
   ---------------------------------------------------------------------------
   Scoped to #solutions-hero: .hero / .product-hero / .hero-bg are shared by
   many pages and must not change elsewhere.

   The teacher and panel occupy 58%-100% of the photo, so the copy column and
   the veil both finish before that. Taking the image's own 4:3 ratio means
   `cover` crops nothing, so that 58% figure holds at every width.
   ========================================================================= */
/* Height band rather than the image's own ratio. This photo is 4:3, so
   honouring it would make the hero 1440px tall on a 1920px screen -- taller
   than the viewport, with nothing but hero on first paint.
   A wide band crops the classroom top and bottom instead, and because the
   box stays WIDER than 4:3, `cover` scales to width and crops only
   vertically -- so the teacher's horizontal position (58%) is preserved,
   which is what the veil stops are tuned against. */
#solutions-hero {
  min-height: clamp(460px, 62vh, 760px);
  height: auto;
}

#solutions-hero .hero-bg-overlay {
  /* Was clearing at 80%, which veiled the teacher. Now clear by 56%. */
  background: linear-gradient(
    to right,
    #f2f0f5 0%,
    #f2f0f5 24%,
    rgba(242, 240, 245, 0.88) 36%,
    rgba(242, 240, 245, 0.45) 47%,
    rgba(242, 240, 245, 0) 56%
  );
}

#solutions-hero .hero-copy {
  width: min(640px, 44%);
  max-width: none;
}

@media (max-width: 900px) {
  /* Copy and classroom keep sharing the frame; the text scales down rather
     than the veil going solid and hiding the photo. */
  #solutions-hero .hero-copy {
    width: min(320px, 42%);
  }

  #solutions-hero .hero-copy h1 {
    font-size: clamp(1.05rem, 2.5vw, 1.7rem);
  }

  #solutions-hero .hero-copy > p:not(.eyebrow) {
    max-width: 32ch;
    margin-top: 8px;
    font-size: clamp(0.78rem, 1.5vw, 0.95rem);
    line-height: 1.5;
  }

  #solutions-hero .hero-actions {
    margin-top: 14px;
    gap: 8px;
  }

  #solutions-hero .button {
    min-height: 40px;
    padding: 9px 14px;
    font-size: 0.84rem;
  }
}

/* Below this the copy can't sit beside the subject, so the ratio is
   released (height follows the content) and the veil goes near-solid. */
@media (max-width: 620px) {
  /* Below this the box would become taller than 4:3, which makes `cover`
     crop horizontally and slide the teacher out of position -- so the
     height floor drops and the veil goes solid instead. */
  #solutions-hero {
    min-height: 0;
  }

  #solutions-hero .hero-bg-overlay {
    background: rgba(242, 240, 245, 0.9);
  }

  #solutions-hero .hero-copy {
    width: 100%;
  }

  /* The headline keeps its 18ch measure here (full-width lines would be
     too long to read), but `h1 { margin: 0 }` left-aligns that narrower
     block inside the now full-width centered copy -- so the text looked
     centered while the block sat hard left. Auto side margins center the
     block itself so it lines up with the paragraph and buttons. */
  #solutions-hero .hero-copy h1 {
    margin-left: auto;
    margin-right: auto;
  }

  #solutions-hero .hero-copy > p:not(.eyebrow) {
    max-width: none;
  }
}
