/**
 * Single device page.
 *
 * The catalog app cannot supply these styles: its CSS is compiled into its JS bundle and injected
 * into a shadow root, which is exactly what stops it leaking into the host page - so it also
 * cannot reach out to a server-rendered page. This is the device page's own stylesheet.
 *
 * Plain CSS rather than SCSS on purpose. The plugin has no build step, and adding one for a single
 * stylesheet would mean a device-page style change could only be made by someone with the frontend
 * project checked out and installed. A theme can also override it as-is.
 *
 * Every selector is scoped under `.calamp-device`, so nothing here can affect the rest of the
 * site. The tokens below are declared on that root rather than `:root` for the same reason - and
 * because it means a theme can restyle the page by overriding tokens instead of fighting rules.
 *
 * Typography is deliberately not set. This page is ordinary document DOM, so it inherits the
 * theme's font stack the way any other template does; only sizes, weights and colours are stated.
 * (The catalog app needs the custom-property dance precisely because a shadow root does not
 * inherit declarations - that problem does not exist here.)
 *
 * **Sizes have a 1rem floor.** Several rules here were ported from the mockup at .8-.95rem, which
 * is 12.8-15.2px; nothing a visitor reads is now below 1rem. `rem` is the right unit on this page -
 * unlike in the app, where it would resolve against the host document - and the theme sets no root
 * font-size override, so 1rem really is 16px. The single exception is
 * `.calamp-device__gallery-count`, documented at the rule.
 */

.calamp-device {
  /* Brand palette, matching the catalog app's tokens so the two read as one system. */
  --calamp-cyan: #00afd7;
  --calamp-navy: #0f202f;
  --calamp-navy-deep: #051625;
  --calamp-navy-800: #253746;
  --calamp-light: #dde5ed;
  --calamp-gray-600: #4f4f4f;
  --calamp-gray-400: #838383;

  /* Semantic roles. */
  --calamp-ink: var(--calamp-navy-800);
  --calamp-muted: var(--calamp-gray-600);
  --calamp-faint: var(--calamp-gray-400);
  --calamp-divider: var(--calamp-light);
  --calamp-canvas: #fff;
  --calamp-surface: #f4f8fa;
  --calamp-table-head: var(--calamp-navy);

  /* Shape and rhythm. */
  --calamp-radius: 12px;
  --calamp-radius-lg: 20px;
  --calamp-shadow: 0 16px 42px -32px rgba(5, 22, 37, 0.55);
  --calamp-gutter: clamp(16px, 4vw, 40px);
  --calamp-max: 1240px;

  /* How far below the viewport top the sticky contents nav parks. Derived from the theme header variable,
     with a fallback.

     Note this is *not* used for anchor offsets: in-page links are handled by the theme's
     scroller, which resolves [data-scroll] and already adds the header height itself, so
     scroll-margin-top would never apply - the sections carry no ids for the browser to navigate
     to natively. */
  --calamp-header-offset: calc(var(--header-height, 96px) + 1em);

  color: var(--calamp-ink);
}

.calamp-device *,
.calamp-device *::before,
.calamp-device *::after {
  box-sizing: border-box;
}

/* The theme normally provides this; included so the table captions stay hidden regardless. */
.calamp-device .screen-reader-text {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  border: 0;
  white-space: nowrap;
}

/* ---------------------------------------------------------------- breadcrumbs */

.calamp-device__breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 9px;
  width: min(var(--calamp-max), 100%);
  margin: 0 auto;
  padding: 24px var(--calamp-gutter) 6px;
  color: var(--calamp-muted);
  font-size: 1rem;
}

.calamp-device__breadcrumbs a {
  color: var(--calamp-muted);
  text-decoration: none;
}

.calamp-device__breadcrumbs a:hover,
.calamp-device__breadcrumbs a:focus-visible {
  color: var(--calamp-cyan);
  text-decoration: underline;
}

/* ---------------------------------------------------------------- hero */

.calamp-device__hero {
  width: min(var(--calamp-max), 100%);
  margin: 0 auto;
  padding: 8px var(--calamp-gutter) clamp(40px, 6vw, 72px);
}

.calamp-device__name {
  margin: 0 0 10px;
  padding: 0 0 10px;
  color: var(--calamp-cyan);
  border-bottom: 1px solid;
  font-size: clamp(2.2rem, 5vw, 3.8rem);
  line-height: 1.05;
}

.calamp-device__subheader {
  margin: 0;
  color: var(--calamp-navy);
  font-size: clamp(1.05rem, 1.6vw, 1.4rem);
  font-weight: 700;
  line-height: 1.3;
}

.calamp-device__hero-body {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(28px, 5vw, 72px);
  align-items: center;
  margin-top: clamp(24px, 3vw, 40px);
}

.calamp-device__description {
  margin: 0;
  color: var(--calamp-muted);
  line-height: 1.6;
}

.calamp-device__highlights {
  display: grid;
  gap: 10px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
}

/* An icon per highlight rather than a bullet, matching the mockup. The icon is doing real work
   here: these lists are a dozen near-identical sentences, and the icon is what makes them
   scannable. DeviceView::iconForHighlight() picks it from the text. */
.calamp-device__highlights li {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 10px;
  align-items: start;
  line-height: 1.5;
  font-weight: bold;
}

.calamp-device__highlight-icon {
  display: grid;
  width: 22px;
  height: 22px;
  place-items: center;
  color: var(--calamp-cyan);
  /* The icon sits on the first line of text rather than the top of the box, so a highlight that
     wraps to two lines still reads as one item. */
  margin-top: 0.1em;
}

.calamp-device__highlight-icon svg {
  width: 18px;
  height: 18px;
}

/* Inheriting the list's color is why these are inlined rather than <img>. The icons already
   declare fill/stroke themselves; this is a fallback in case a future one does not, and matches
   what .calamp-device__spec-icon svg does. */
.calamp-device__highlight-icon svg {
  fill: none;
  stroke: currentColor;
}

/* ---------------------------------------------------------------- gallery */

/* The mockup's .detail-stage: one rounded, bordered panel holding the whole gallery - stage,
   arrows, counter and thumbnails - on a tint just off the page white. The tint is what gives a
   transparent PNG render an edge to sit against; without it these product shots float. */
.calamp-device__gallery {
  width: min(100%, 560px);
  min-width: 0;
  margin-inline: auto;
  padding: clamp(16px, 3vw, 26px);
  border: 1px solid var(--calamp-divider);
  border-radius: var(--calamp-radius-lg);
}

.calamp-device__gallery-stage {
  position: relative;
  width: 100%;
  min-width: 0;
  background: var(--calamp-surface);
}

/* A fixed stage height, not the image's natural one. These renders vary from square to wide, so
   an auto height makes the panel jump every time an arrow is pressed - and it is the panel, not
   the image, that the eye is anchored on. */
.calamp-device__image {
  display: grid;
  /* Explicit tracks, not the implicit `auto` ones a bare `display: grid` creates. An auto track
     takes its base size from the image's intrinsic height, so a portrait render grows the track
     past the stage, `height: 100%` then resolves against the grown track and never clamps, and
     `object-fit: contain` has nothing left to contain against. The image escapes the panel. */
  grid-template-rows: minmax(0, 1fr);
  grid-template-columns: minmax(0, 1fr);
  width: 100%;
  height: 390px;
  min-width: 0;
  min-height: 0;
  margin: 0;
  padding: 0 clamp(0px, 6vw, 46px);
  place-items: center;
}

/* Only the active slide is shown. Without the script that is slide one, which is a working
   single-image gallery rather than a broken multi-image one. */
.calamp-device__image:not(.is-active) {
  display: none;
}

/* `max-*` rather than `width`/`height: 100%`: a max clamps the render to the track without
   forcing a portrait image to fill a wider one, and the `min-*: 0` pair overrides the automatic
   minimum size a grid item otherwise takes from its own content. */
.calamp-device__image img {
  max-width: 100%;
  max-height: 100%;
  min-width: 0;
  min-height: 0;
  /* contain, because these are product renders on transparent backgrounds with varying aspect
     ratios - cropping any of them would cut off a connector or an antenna. */
  object-fit: contain;
}

.calamp-device__gallery-arrow {
  position: absolute;
  z-index: 3;
  top: 50%;
  display: grid;
  width: 34px;
  height: 44px;
  padding: 0;
  place-items: center;
  /* The theme styles bare buttons as pill CTAs, so the reset is explicit rather than relying on
     the UA default - min-width and box-shadow in particular would otherwise cover the render. */
  min-width: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  color: var(--calamp-ink);
  background: transparent;
  cursor: pointer;
  transform: translateY(-50%);
  transition: color 180ms ease-out, transform 180ms ease-out;
}

.calamp-device__gallery-arrow:hover,
.calamp-device__gallery-arrow:focus-visible {
  color: var(--calamp-cyan);
  transform: translateY(-50%) scale(1.05);
}

.calamp-device__gallery-arrow--prev {
  left: 0;
}

.calamp-device__gallery-arrow--next {
  right: 0;
}

.calamp-device__gallery-arrow-icon {
  display: grid;
  place-items: center;
}

.calamp-device__gallery-arrow-icon svg {
  width: 22px;
  height: 22px;
}

.calamp-device__gallery-arrow-icon svg {
  fill: none;
  stroke: currentColor;
}

.calamp-device__gallery-count {
  position: absolute;
  z-index: 3;
  right: 50%;
  bottom: -14px;
  margin: 0;
  padding: 5px 10px;
  border: 1px solid var(--calamp-divider);
  border-radius: 999px;
  color: var(--calamp-muted);
  background: rgba(255, 255, 255, 0.94);
  box-shadow: 0 6px 18px rgba(5, 22, 37, 0.12);
  /* The one size below the 1rem floor on this page, and deliberately so: this is a numeric badge
     that annotates the image rather than text anyone reads. It is the server-rendered twin of the
     catalog app's `.gallery__count`, which is 12px for the same reason - the two have to agree or
     the same pill reads at two sizes across the two surfaces. */
  font-size: 0.75rem;
  transform: translateX(50%);
}

/* justify-content: center centers a short strip; safe center is what stops a strip wider than the
   viewport from having its first thumbnail pushed out of reach on the unscrollable side. Flexbox
   overflow is not symmetrical, so plain center is genuinely lossy here. */
.calamp-device__gallery-thumbs {
  display: flex;
  width: 100%;
  min-width: 0;
  /* Clear of the counter pill, which hangs 14px below the stage. */
  margin: 30px 0 0;
  padding: 4px 0 8px;
  gap: 9px;
  justify-content: safe center;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}

.calamp-device__gallery-thumbs::-webkit-scrollbar {
  display: none;
}

.calamp-device__gallery-thumb {
  display: grid;
  /* Same track reasoning as the stage above - the thumbnails draw from the same renders. */
  grid-template-rows: minmax(0, 1fr);
  grid-template-columns: minmax(0, 1fr);
  width: 68px;
  height: 56px;
  flex: 0 0 auto;
  min-width: 0;
  min-height: 0;
  padding: 5px;
  place-items: center;
  border: 1px solid var(--calamp-divider);
  border-radius: 8px;
  box-shadow: none;
  background: var(--calamp-canvas);
  cursor: pointer;
  scroll-snap-align: center;
  transition: border-color 180ms ease-out, box-shadow 180ms ease-out, transform 180ms ease-out;
}

.calamp-device__gallery-thumb:hover {
  border-color: var(--calamp-faint);
  transform: translateY(-2px);
}

.calamp-device__gallery-thumb.is-active {
  border-color: var(--calamp-cyan);
  box-shadow: 0 0 0 3px rgba(0, 175, 215, 0.14);
}

.calamp-device__gallery-thumb img {
  max-width: 100%;
  max-height: 100%;
  min-width: 0;
  min-height: 0;
  object-fit: contain;
}

/* ---------------------------------------------------------------- buttons */

.calamp-device__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 28px;
}

.calamp-device__button {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  padding: 0 22px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  transition: background-color 180ms ease-out, color 180ms ease-out, border-color 180ms ease-out;
}

.calamp-device__button--primary {
  color: var(--calamp-canvas);
  background: var(--calamp-cyan);
}

.calamp-device__button--primary:hover,
.calamp-device__button--primary:focus-visible {
  color: var(--calamp-canvas);
  background: var(--calamp-navy);
}

.calamp-device__button--secondary {
  color: var(--calamp-ink);
  border-color: var(--calamp-divider);
  background: var(--calamp-canvas);
}

.calamp-device__button--secondary:hover,
.calamp-device__button--secondary:focus-visible {
  border-color: var(--calamp-cyan);
  color: var(--calamp-cyan);
}

.calamp-device :focus-visible {
  outline: 3px solid var(--calamp-cyan);
  outline-offset: 3px;
}

/* ---------------------------------------------------------------- specifications */

.calamp-device__specs {
  padding: clamp(40px, 6vw, 80px) 0;
  background: var(--calamp-surface);
}

.calamp-device__specs > h2 {
  width: min(var(--calamp-max), 100%);
  margin: 0 auto clamp(20px, 3vw, 32px);
  padding: 0 var(--calamp-gutter);
  font-size: clamp(1.6rem, 3vw, 2.2rem);
}

.calamp-device__contents {
  position: sticky;
  top: var(--calamp-header-offset);
  display: flex;
  flex-direction: column;
  align-self: start;
  gap: 3px;
  padding: 14px 12px;
  border: 1px solid var(--calamp-divider);
  border-radius: var(--calamp-radius-lg);
  background: rgba(255, 255, 255, 0.96);
  box-shadow: var(--calamp-shadow);
}

.calamp-device__contents a {
  display: flex;
  min-height: 40px;
  align-items: center;
  padding: 8px 10px;
  border-radius: 10px;
  color: var(--calamp-muted);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.3;
  text-decoration: none;
  transition: color 180ms ease-out, background-color 180ms ease-out;
}

.calamp-device__contents a:hover,
.calamp-device__contents a:focus-visible {
  color: var(--calamp-navy);
  background: var(--calamp-surface);
}

/* The section stays full-bleed so its background spans the viewport; its contents are centred by
   the wrapper. That split is why the template has a __spec-layout element at all. */
.calamp-device__spec-layout {
  width: min(var(--calamp-max), 100%);
  margin: 0 auto;
  padding: 0 var(--calamp-gutter);
}

.calamp-device__spec-sections {
  display: grid;
  min-width: 0;
  gap: 24px;
}

@media (min-width: 900px) {
  /* Nav beside the tables rather than above them, which is the whole point of it being sticky. */
  .calamp-device__spec-layout {
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr);
    gap: 24px;
    align-items: start;
  }
}

.calamp-device__spec-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  overflow: hidden;
  border-radius: var(--calamp-radius);
  background: var(--calamp-canvas);
  box-shadow: var(--calamp-shadow);
}

.calamp-device__spec-table thead th {
  padding: 14px 18px;
  color: var(--calamp-canvas);
  background: var(--calamp-table-head);
  font-size: 1rem;
  font-weight: 700;
  text-align: left;
}

.calamp-device__spec-table thead th > span:not(.calamp-device__spec-icon) {
  vertical-align: middle;
}

.calamp-device__spec-icon {
  display: inline-flex;
  width: 20px;
  height: 20px;
  margin-right: 10px;
  vertical-align: middle;
  align-items: center;
  justify-content: center;
  color: var(--calamp-cyan);
}

.calamp-device__spec-icon svg {
  width: 100%;
  height: 100%;
  /* Inheriting the header's colour is why these are inlined rather than <img>. The icons already
     declare fill/stroke themselves; these are a fallback in case a future one does not. Their own
     stroke-width is deliberately left alone - overriding it thinned every icon at once. */
  fill: none;
  stroke: currentColor;
}

.calamp-device__spec-table th[scope="row"],
.calamp-device__spec-table td {
  padding: 12px 18px;
  border-top: 1px solid var(--calamp-divider);
  font-size: 1rem;
  line-height: 1.5;
  text-align: left;
  vertical-align: top;
}

.calamp-device__spec-table th[scope="row"] {
  width: 34%;
  color: var(--calamp-muted);
  font-weight: 700;
}

.calamp-device__spec-table td {
  color: var(--calamp-ink);
  /* Newlines in dimensions, battery life and power consumption are meaningful; the template sets
     pre-line inline and this keeps long values from overflowing the cell. */
  overflow-wrap: anywhere;
}

.calamp-device__spec-table tbody tr:nth-child(even) {
  background: rgba(244, 248, 250, 0.6);
}

/* ---------------------------------------------------------------- footnotes */

.calamp-device__footnotes {
  margin-top: 4px;
}

.calamp-device__footnote {
  margin: 0 0 6px;
  color: var(--calamp-faint);
  font-size: 1rem;
  line-height: 1.5;
}

/* ---------------------------------------------------------------- related */

.calamp-device__related {
  width: min(var(--calamp-max), 100%);
  margin: 0 auto;
  padding: clamp(40px, 6vw, 80px) var(--calamp-gutter);
}

.calamp-device__related-head {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: clamp(18px, 2.5vw, 28px);
}

.calamp-device__related-head h2 {
  margin: 0;
  font-size: clamp(1.5rem, 2.6vw, 2rem);
}

.calamp-device__related-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.calamp-device__related-card > a {
  display: grid;
  height: 100%;
  gap: 8px;
  padding: 22px;
  border: 1px solid var(--calamp-divider);
  border-radius: var(--calamp-radius-lg);
  color: inherit;
  background: var(--calamp-canvas);
  text-decoration: none;
  transition: transform 180ms ease-out, box-shadow 180ms ease-out;
}

.calamp-device__related-card > a:hover,
.calamp-device__related-card > a:focus-visible {
  transform: translateY(-2px);
  box-shadow: var(--calamp-shadow);
}

.calamp-device__related-card img {
  width: 100%;
  height: 150px;
  object-fit: contain;
}

.calamp-device__related-name {
  color: var(--calamp-cyan);
  font-size: 1.1rem;
  font-weight: 700;
}

.calamp-device__related-subheader {
  color: var(--calamp-muted);
  font-size: 1rem;
  line-height: 1.45;
}

/* ---------------------------------------------------------------- narrow screens */

/* ---------------------------------------------------------------- request a quote */

/* The shared eyebrow rule lives in quote-dialog.css, which is enqueued alongside this file on
   every device page - it is needed by the dialog, which the catalog renders without this
   stylesheet, and the CTA banner below uses the same class. */

/* Full-bleed, unlike every other section here, which is what makes it read as a band closing the
   page rather than one more block in the column. */
.calamp-device__cta {
  margin-top: clamp(40px, 6vw, 80px);
  color: var(--calamp-canvas);
  background: var(--calamp-navy-deep);
}

.calamp-device__cta-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  width: min(var(--calamp-max), 100%);
  margin: 0 auto;
  padding: clamp(40px, 6vw, 58px) var(--calamp-gutter);
}

.calamp-device__cta-copy {
  min-width: 0;
}

.calamp-device__cta-copy h2 {
  max-width: 720px;
  margin: 0 0 12px;
  color: var(--calamp-canvas);
}

.calamp-device__cta-copy p:not(.calamp-device__eyebrow) {
  max-width: 650px;
  margin: 0;
  /* Not --calamp-muted: that token is a grey chosen against white and disappears here. */
  color: rgba(255, 255, 255, 0.72);
}

.calamp-device__button--cta {
  flex: 0 0 auto;
  color: var(--calamp-navy-deep);
  border-color: var(--calamp-cyan);
  background: var(--calamp-cyan);
  cursor: pointer;
}

.calamp-device__button--cta:hover,
.calamp-device__button--cta:focus-visible {
  color: var(--calamp-navy-deep);
  border-color: var(--calamp-canvas);
  background: var(--calamp-canvas);
}


@media (max-width: 899px) {
  .calamp-device__hero-body {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Image first on desktop, but the name and subheader are already above both, so the natural
     source order reads correctly here without reordering. */
  .calamp-device__contents {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    margin-bottom: 20px;
  }

  .calamp-device__spec-table th[scope="row"] {
    width: 42%;
  }

  /* The button drops below the copy rather than shrinking beside it - a 44px pill next to two
     lines of prose has nowhere left to go at this width. */
  .calamp-device__cta-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
  }
}

@media (max-width: 599px) {
  /* Below this width a two-column spec row leaves no room for either side, so the label sits
     above its value.

     Every part of the table has to become a block, not just the cells. A `tr` left as
     `table-row` keeps its children in a row formatting context, so the label and value stay
     side by side however the cells themselves are declared — and a `table` left as `table`
     re-establishes that context around them. `table-layout` and `border-collapse` stop applying
     once these are blocks, which is why the row divider moves onto the `tr` below. */
  .calamp-device__spec-table,
  .calamp-device__spec-table thead,
  .calamp-device__spec-table tbody,
  .calamp-device__spec-table tr,
  .calamp-device__spec-table th,
  .calamp-device__spec-table td {
    display: block;
    width: auto;
  }

  .calamp-device__spec-table thead th,
  .calamp-device__spec-table th[scope="row"],
  .calamp-device__spec-table td {
    padding: 10px 12px;
  }

  /* The row owns the divider now that cells are stacked; a border on the cells would draw a line
     between a label and its own value. */
  .calamp-device__spec-table th[scope="row"],
  .calamp-device__spec-table td {
    border-top: 0;
  }

  .calamp-device__spec-table tbody tr + tr {
    border-top: 1px solid var(--calamp-divider);
  }

  .calamp-device__spec-table th[scope="row"] {
    padding-bottom: 2px;
  }

  .calamp-device__spec-table td {
    padding-top: 0;
  }

  /* The arrows overlap the render at this width, which is the trade the mockup makes too - the
     alternative is a stage narrow enough that the product is unreadable. They keep a 40px touch
     target while the padding holds the image clear of them. */
  .calamp-device__image {
    height: 300px;
    padding: 0 44px;
  }

  .calamp-device__gallery-arrow {
    width: 40px;
    height: 40px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .calamp-device * {
    transition: none !important;
  }

  .calamp-device__related-card > a:hover {
    transform: none;
  }
}
