/* ==========================================================================
   Iron Acre — Interior page components

   Shared by every page, including index.html, so the stylesheet set is
   identical everywhere and stays cacheable. Nothing here is page-specific:
   each block is a component that more than one page uses, or that a future
   page will use.

   Load order matters — this file comes after sections.css and assumes the
   tokens, .container/.section rhythm, .card, and .btn systems already exist.
   Nothing here redefines them.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Page hero
   Interior counterpart to the homepage's full-viewport .hero. Shorter, and it
   clears the fixed header rather than sitting under it.
   -------------------------------------------------------------------------- */
.page-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block-start: calc(var(--header-h) + var(--space-16));
  padding-block-end: var(--section-y);
  border-block-end: 1px solid var(--c-border);
}

/* Atmospheric wash. Two offset radials read as depth without needing an
   image, and every interior page gets the same treatment for cohesion. */
.page-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(
      70% 60% at 18% 0%,
      rgba(23, 64, 42, 0.55) 0%,
      rgba(23, 64, 42, 0) 62%
    ),
    radial-gradient(
      55% 50% at 92% 8%,
      rgba(159, 232, 112, 0.09) 0%,
      rgba(159, 232, 112, 0) 60%
    );
  pointer-events: none;
}

/* Hairline horizon that keeps the wash from ending abruptly. */
.page-hero::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: -1;
  block-size: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--c-border-strong) 22%,
    var(--c-border-strong) 78%,
    transparent
  );
  pointer-events: none;
}

.page-hero__inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  max-inline-size: 46ch;
}

.page-hero__title {
  font-size: var(--fs-4xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
}

.page-hero__title em {
  font-style: normal;
  color: var(--c-lime);
}

.page-hero__lede {
  color: var(--c-text-mute);
  font-size: var(--fs-lg);
  line-height: var(--lh-relaxed);
  max-inline-size: 60ch;
}

.page-hero__actions {
  margin-block-start: var(--space-4);
}

/* The column's reading measure is a little narrower than two large buttons
   side by side, which made them stack while empty space sat beside them. The
   measure only needs to apply to the text, so above the point where the
   container is comfortably wider than the measure, let the row size to its
   content and overhang the text column. */
@media (min-width: 700px) {
  .page-hero__actions {
    inline-size: max-content;
  }
}

/* Wide variant for pages whose hero introduces a grid rather than a story. */
.page-hero--wide .page-hero__inner {
  max-inline-size: 62ch;
}

@media (min-width: 900px) {
  .page-hero {
    padding-block-start: calc(var(--header-h-lg) + var(--space-20));
  }
}

/* Conversion pages: the hero is an introduction, not a destination, so it
   hands over to the content quickly instead of stacking two section paddings
   into a dead band before the form. */
.page-hero--compact {
  padding-block-end: var(--space-10);
}

/* --------------------------------------------------------------------------
   Split page hero
   For the flagship page, where the hero introduces a product and a supporting
   visual earns its place. Single column until there is genuinely room for two.
   -------------------------------------------------------------------------- */
@media (min-width: 1000px) {
  .page-hero--split .container {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
    gap: var(--space-16);
    align-items: center;
  }

  .page-hero--split .page-hero__inner {
    max-inline-size: 40ch;
  }
}

/* Hidden below the split breakpoint: at phone and tablet widths the visual
   would push the CTAs below the fold, and the simulator right underneath
   already shows the same thing. */
.page-hero__visual {
  display: none;
}

@media (min-width: 1000px) {
  .page-hero__visual {
    display: block;
    position: relative;
  }

  .page-hero__visual::before {
    content: "";
    position: absolute;
    inset: -12% 0 -6%;
    z-index: -1;
    background: radial-gradient(
      50% 50% at 55% 50%,
      var(--split-glow, var(--c-lime)) 0%,
      transparent 68%
    );
    opacity: 0.16;
    filter: blur(46px);
    pointer-events: none;
  }

  .page-hero__visual .split__frame {
    /* A slight rotation and lift separates it from the flat page behind it.
       Small enough to read as depth rather than as a tilted image. */
    transform: perspective(1400px) rotateY(-6deg) rotateX(1.5deg) translateZ(0);
    transition: transform var(--dur-slow) var(--ease-out),
      border-color var(--dur-base) var(--ease-out);
  }

  .page-hero__visual .split__frame:hover {
    transform: perspective(1400px) rotateY(-3deg) rotateX(0.75deg) translateZ(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .page-hero__visual .split__frame,
  .page-hero__visual .split__frame:hover {
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   Breadcrumb
   -------------------------------------------------------------------------- */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-block-end: var(--space-2);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  color: var(--c-text-faint);
}

.crumbs a {
  color: var(--c-text-mute);
  text-decoration: none;
}

.crumbs a:hover {
  color: var(--c-text);
}

.crumbs__sep {
  opacity: 0.5;
}

/* --------------------------------------------------------------------------
   Prose
   Long-form copy blocks on About and the FAQ intro.
   -------------------------------------------------------------------------- */
.prose {
  max-inline-size: 68ch;
  color: var(--c-text-mute);
  font-size: var(--fs-lg);
  line-height: var(--lh-relaxed);
}

.prose > * + * {
  margin-block-start: var(--space-6);
}

.prose strong {
  color: var(--c-text);
  font-weight: var(--fw-semibold);
}

/* --------------------------------------------------------------------------
   Media split
   Text beside a framed visual. Alternates sides down a page to build rhythm.
   -------------------------------------------------------------------------- */
.split {
  display: grid;
  gap: var(--space-10);
  align-items: center;
}

.split__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.split__title {
  font-size: var(--fs-2xl);
  line-height: var(--lh-snug);
}

.split__text {
  color: var(--c-text-mute);
  line-height: var(--lh-relaxed);
}

/* Framed visual with a tinted glow behind it, matching the simulator's
   treatment so the two read as the same family. */
.split__media {
  position: relative;
}

.split__media::before {
  content: "";
  position: absolute;
  /* No horizontal bleed: a negative inline inset here scrolls the page
     sideways inside the container's gutter at tablet widths. */
  inset: -8% 0 4%;
  z-index: -1;
  background: radial-gradient(
    50% 50% at 50% 45%,
    var(--split-glow, var(--c-lime)) 0%,
    transparent 70%
  );
  opacity: 0.12;
  filter: blur(38px);
  pointer-events: none;
}

.split__frame {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  background-color: var(--c-surface);
  box-shadow: var(--shadow-lg);
  transition: border-color var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

.split__frame > img {
  display: block;
  inline-size: 100%;
  block-size: auto;
}

.split__frame:hover {
  border-color: var(--c-border-strong);
}

.split__caption {
  margin-block-start: var(--space-3);
  color: var(--c-text-faint);
  font-size: var(--fs-xs);
}

@media (min-width: 900px) {
  .split {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-16);
  }

  /* Reversed variant puts the media first without reordering the markup, so
     the reading order stays text-then-image for screen readers. */
  .split--reverse .split__body {
    order: 2;
  }
}

/* --------------------------------------------------------------------------
   Use-case tiles
   Occasions and moods on the lighting page. Depth on hover, nothing moving
   until the visitor points at it.
   -------------------------------------------------------------------------- */
.usecase {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-6);
  overflow: hidden;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  background-color: var(--c-surface);
  transition: border-color var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}

/* Each tile carries its own accent via --tile-glow, set inline per item. */
.usecase::before {
  content: "";
  position: absolute;
  inset-block-start: -40%;
  inset-inline-start: -20%;
  inline-size: 90%;
  aspect-ratio: 1;
  background: radial-gradient(
    50% 50% at 50% 50%,
    var(--tile-glow, var(--c-lime)) 0%,
    transparent 68%
  );
  opacity: 0.14;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out);
}

.usecase:hover {
  border-color: var(--c-border-strong);
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}

.usecase:hover::before {
  opacity: 0.22;
}

.usecase__swatch {
  position: relative;
  inline-size: 34px;
  block-size: 34px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--c-border-strong);
  background: var(--tile-glow, var(--c-lime));
  box-shadow: 0 0 18px -4px var(--tile-glow, var(--c-lime));
}

.usecase__title {
  position: relative;
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
}

.usecase__text {
  position: relative;
  color: var(--c-text-mute);
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
}

/* --------------------------------------------------------------------------
   Feature list
   Checked capability rows. Used on the lighting and services pages.
   -------------------------------------------------------------------------- */
.checks {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.checks li {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: var(--space-3);
  align-items: start;
  color: var(--c-text-mute);
  line-height: var(--lh-relaxed);
}

.checks svg {
  inline-size: 22px;
  block-size: 22px;
  margin-block-start: 2px;
  fill: none;
  stroke: var(--c-lime);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --------------------------------------------------------------------------
   FAQ
   Native <details> so it works without JavaScript and is keyboard operable
   for free. No ARIA is added, because the element already conveys state.
   -------------------------------------------------------------------------- */
/* Two columns on desktop: the section heading holds the left, questions the
   right. A single narrow column of accordions strands most of a 1440px
   viewport, and the heading has nowhere useful to sit. */
.faq-layout {
  display: grid;
  gap: var(--space-10);
  align-items: start;
}

@media (min-width: 900px) {
  .faq-layout {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    gap: var(--space-16);
  }

  /* The heading tracks the reader down a long list of questions. */
  .faq-layout__aside {
    position: sticky;
    inset-block-start: calc(var(--header-h-lg) + var(--space-10));
  }

  .faq-layout .section__head {
    margin-block-end: var(--space-6);
  }
}

.faq {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-inline-size: 0;
  max-inline-size: 80ch;
}

.faq__item {
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
  background-color: var(--c-surface);
  transition: border-color var(--dur-base) var(--ease-out);
}

.faq__item:hover,
.faq__item[open] {
  border-color: var(--c-border-strong);
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  /* Comfortably past the 44px target on every viewport. */
  min-block-size: 60px;
  padding: var(--space-4) var(--space-5);
  color: var(--c-text);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  cursor: pointer;
  list-style: none;
}

/* Hide the native disclosure marker in both engines; the +/- below replaces it. */
.faq__q::-webkit-details-marker {
  display: none;
}

.faq__q::marker {
  content: "";
}

.faq__icon {
  position: relative;
  flex: none;
  inline-size: 20px;
  block-size: 20px;
}

.faq__icon::before,
.faq__icon::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  background-color: var(--c-lime);
  translate: -50% -50%;
  transition: opacity var(--dur-base) var(--ease-out),
    rotate var(--dur-base) var(--ease-out);
}

.faq__icon::before {
  inline-size: 14px;
  block-size: 2px;
}

.faq__icon::after {
  inline-size: 2px;
  block-size: 14px;
}

.faq__item[open] .faq__icon::after {
  opacity: 0;
  rotate: 90deg;
}

.faq__a {
  padding: 0 var(--space-5) var(--space-5);
  color: var(--c-text-mute);
  line-height: var(--lh-relaxed);
  max-inline-size: 70ch;
}

.faq__a > * + * {
  margin-block-start: var(--space-4);
}

/* --------------------------------------------------------------------------
   Gallery
   -------------------------------------------------------------------------- */
.gallery-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-block-end: var(--space-8);
}

.filter-btn {
  min-block-size: 44px;
  padding: var(--space-2) var(--space-5);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-pill);
  background-color: var(--c-surface);
  color: var(--c-text-mute);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  white-space: nowrap;
  transition: border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out);
}

.filter-btn:hover {
  border-color: var(--c-border-strong);
  color: var(--c-text);
  background-color: var(--c-surface-2);
}

.filter-btn[aria-pressed="true"] {
  border-color: var(--c-lime);
  background-color: var(--c-lime-soft);
  color: var(--c-text);
}

/* Two-up even on phones: these photographs read fine at half width, the
   scroll is half as long, and the lead tile going full-width gives the page a
   large-small-small rhythm instead of a uniform stack. */
.tiles {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(2, 1fr);
  margin: 0;
  padding: 0;
  list-style: none;
}

.tile[data-lead] {
  grid-column: span 2;
}

@media (min-width: 600px) {
  .tiles {
    gap: var(--space-5);
  }

  /* At two comfortable columns the lead keeps its double width but trades up
     to a wider crop so its row does not tower over the pairs below. */
  .tile[data-lead] .tile__media {
    aspect-ratio: 21 / 9;
  }
}

@media (min-width: 1000px) {
  .tiles {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-6);
  }

  /* Lead tiles anchor a 2×2 area beside a column of regular tiles. The media
     box abandons its own aspect ratio and fills whatever height the two
     neighbouring rows produce, so row sizing is still governed by the small
     tiles and the grid never feeds back into itself. */
  .tile[data-lead] {
    grid-row: span 2;
  }

  .tile[data-lead] .tile__btn {
    display: flex;
    flex-direction: column;
    block-size: 100%;
  }

  .tile[data-lead] .tile__media {
    aspect-ratio: auto;
    flex: 1;
    min-block-size: 0;
  }

  /* Taking the image out of flow is what makes the claim above structural
     rather than a coincidence of ratios. In flow, a lead spanning two auto
     rows contributes its own intrinsic height to those rows, so a tall
     photograph would push them taller and then shrink them once a
     differently-proportioned file loaded. Out of flow it contributes nothing,
     so row heights depend only on the pinned small tiles — whatever aspect
     ratio the real photography turns out to have. */
  .tile[data-lead] .tile__media > img {
    position: absolute;
    inset: 0;
  }
}

.tile {
  margin: 0;
}

/* The whole tile is one button so touch targets are generous and there is a
   single tab stop per image rather than two. */
.tile__btn {
  display: block;
  inline-size: 100%;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  background-color: var(--c-surface);
  text-align: start;
  transition: border-color var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}

.tile__btn:hover {
  border-color: var(--c-border-strong);
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}

.tile__media {
  position: relative;
  /* Required. This is a <span>, and aspect-ratio has no effect on a
     non-replaced inline box — without this the ratio below computes but never
     governs, and the tile takes its height from the image instead, resizing
     every tile the moment the artwork loads. */
  display: block;
  overflow: hidden;
  /* Set per item from GALLERY_ITEMS so mixed ratios never cause a reflow. */
  aspect-ratio: var(--tile-ratio, 16 / 9);
  background-color: var(--c-surface-2);
}

.tile__media > img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: scale var(--dur-slow) var(--ease-out);
}

.tile__btn:hover .tile__media > img {
  scale: 1.03;
}

/* Zoom affordance, revealed on hover and always present for touch. */
.tile__zoom {
  position: absolute;
  inset-block-end: var(--space-3);
  inset-inline-end: var(--space-3);
  display: grid;
  place-items: center;
  inline-size: 36px;
  block-size: 36px;
  border-radius: var(--radius-pill);
  background-color: var(--c-scrim);
  color: var(--c-text);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}

.tile__zoom svg {
  inline-size: 18px;
  block-size: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

.tile__btn:hover .tile__zoom,
.tile__btn:focus-visible .tile__zoom {
  opacity: 1;
}

@media (hover: none) {
  .tile__zoom {
    opacity: 1;
  }
}

.tile__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-4) var(--space-5);
}

/* Half-width tiles on phones need a quieter meta bar or it dominates the image. */
@media (max-width: 599px) {
  .tile:not([data-lead]) .tile__meta {
    padding: var(--space-3) var(--space-4);
  }

  .tile:not([data-lead]) .tile__title {
    font-size: var(--fs-sm);
  }
}

.tile__title {
  color: var(--c-text);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
}

.tile__kind {
  color: var(--c-text-faint);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}

.tiles__empty {
  padding: var(--space-10) 0;
  color: var(--c-text-mute);
}

/* --------------------------------------------------------------------------
   Lightbox
   Native <dialog>, which brings modal focus containment, Escape to close, and
   focus restoration to the invoking element with no JavaScript of our own.
   -------------------------------------------------------------------------- */
.lightbox {
  inline-size: min(96vw, 1400px);
  max-inline-size: none;
  max-block-size: 94vh;
  padding: 0;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-lg);
  background-color: var(--c-void);
  color: var(--c-text);
  overflow: hidden;
}

.lightbox::backdrop {
  background-color: rgba(4, 6, 4, 0.86);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.lightbox__figure {
  display: flex;
  flex-direction: column;
  margin: 0;
}

.lightbox__stage {
  position: relative;
  display: grid;
  place-items: center;
  background-color: #000;
  /* Bounded so a tall image cannot push the controls off screen. */
  max-block-size: 78vh;
  overflow: hidden;
}

.lightbox__img {
  display: block;
  max-inline-size: 100%;
  max-block-size: 78vh;
  inline-size: auto;
  block-size: auto;
  object-fit: contain;
}

.lightbox__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-block-start: 1px solid var(--c-border);
  background-color: var(--c-surface);
}

.lightbox__caption {
  min-inline-size: 0;
  color: var(--c-text-mute);
  font-size: var(--fs-sm);
}

.lightbox__caption b {
  display: block;
  color: var(--c-text);
  font-weight: var(--fw-semibold);
}

.lightbox__controls {
  display: flex;
  flex: none;
  gap: var(--space-2);
}

.lightbox__btn {
  display: grid;
  place-items: center;
  /* 44px minimum on every control, including on phones. */
  inline-size: 44px;
  block-size: 44px;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-pill);
  background-color: var(--c-surface-2);
  color: var(--c-text);
  transition: border-color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out);
}

.lightbox__btn:hover {
  border-color: var(--c-border-strong);
  background-color: var(--c-surface-3);
}

.lightbox__btn svg {
  inline-size: 20px;
  block-size: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.lightbox__count {
  align-self: center;
  padding-inline: var(--space-2);
  color: var(--c-text-faint);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media (min-width: 600px) {
  .lightbox__bar {
    padding-inline: var(--space-6);
  }
}

/* --------------------------------------------------------------------------
   Values / story rows
   About page. Numbered rows that accept a photo later without a redesign.
   -------------------------------------------------------------------------- */
.values {
  display: grid;
  gap: var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 700px) {
  .values {
    grid-template-columns: repeat(2, 1fr);
  }
}

.value {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-6);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  background-color: var(--c-surface);
  transition: border-color var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

.value:hover {
  border-color: var(--c-border-strong);
  transform: translateY(-2px);
}

.value__icon {
  display: grid;
  place-items: center;
  inline-size: 40px;
  block-size: 40px;
  border-radius: var(--radius-md);
  background-color: var(--c-lime-soft);
}

.value__icon svg {
  inline-size: 20px;
  block-size: 20px;
  fill: none;
  stroke: var(--c-lime);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.value__title {
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
}

.value__text {
  color: var(--c-text-mute);
  line-height: var(--lh-relaxed);
}

/* Reserved portrait slot. Framed and labelled as a design element, so it
   reads as intentional rather than as a missing image. */
.portrait {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(
      80% 60% at 50% 0%,
      rgba(23, 64, 42, 0.5) 0%,
      rgba(23, 64, 42, 0) 65%
    ),
    var(--c-surface);
}

/* An inner mat line, like a framed print, so the panel reads as composed
   rather than as a box waiting for content. */
.portrait::after {
  content: "";
  position: absolute;
  inset: var(--space-4);
  border: 1px solid var(--c-border);
  border-radius: calc(var(--radius-lg) - 8px);
  pointer-events: none;
}

.portrait__motif {
  inline-size: min(72%, 300px);
  color: var(--c-text-faint);
}

.portrait__motif svg {
  inline-size: 100%;
  block-size: auto;
}

.portrait__lights {
  color: var(--c-lime);
  opacity: 0.7;
}

.portrait__caption {
  position: absolute;
  inset-block-end: var(--space-8);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  color: var(--c-text-faint);
}

/* The future owner photo drops straight in: replace the .portrait contents
   with a single <img> and it fills the frame under the same mat line. */
.portrait > img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* Photo variant: the caption sits on a scrim so it stays legible, and the
   inner mat line is dropped so it does not fight the photograph. */
.portrait--photo::after {
  content: none;
}

.portrait--photo .portrait__caption {
  inset-inline: 0;
  inset-block-end: 0;
  padding: var(--space-10) var(--space-5) var(--space-5);
  text-align: center;
  color: var(--c-text-muted);
  background: linear-gradient(to top, rgb(4 6 4 / 0.78), transparent);
}

/* --------------------------------------------------------------------------
   Quote form
   -------------------------------------------------------------------------- */
.quote-layout {
  display: grid;
  gap: var(--space-12);
  align-items: start;
}

@media (min-width: 1000px) {
  .quote-layout {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: var(--space-16);
  }
}

.form-panel {
  padding: var(--space-6);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  background-color: var(--c-surface);
  box-shadow: var(--shadow-md);
}

@media (min-width: 700px) {
  .form-panel {
    padding: var(--space-10);
  }
}

.form-grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr;
}

@media (min-width: 700px) {
  .form-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .field--full {
    grid-column: 1 / -1;
  }
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-inline-size: 0;
}

.field__label {
  color: var(--c-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
}

.field__optional {
  color: var(--c-text-faint);
  font-weight: var(--fw-regular);
  letter-spacing: 0;
  text-transform: none;
}

.field__control {
  inline-size: 100%;
  min-block-size: 48px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--c-void);
  color: var(--c-text);
  font-family: inherit;
  font-size: var(--fs-base);
  transition: border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.field__control::placeholder {
  color: var(--c-text-faint);
}

.field__control:hover {
  border-color: rgba(244, 246, 241, 0.34);
}

.field__control:focus {
  border-color: var(--c-lime);
  box-shadow: 0 0 0 3px var(--c-lime-soft);
  outline: none;
}

/* Focus-visible keeps the global ring for keyboard users on top of the tint. */
.field__control:focus-visible {
  outline: 3px solid var(--c-focus);
  outline-offset: 2px;
}

textarea.field__control {
  min-block-size: 148px;
  line-height: var(--lh-relaxed);
  resize: vertical;
}

select.field__control {
  appearance: none;
  /* Room for the chevron drawn below. */
  padding-inline-end: var(--space-10);
  background-image: linear-gradient(
      45deg,
      transparent 50%,
      var(--c-text-mute) 50%
    ),
    linear-gradient(135deg, var(--c-text-mute) 50%, transparent 50%);
  background-position: calc(100% - 22px) 52%, calc(100% - 16px) 52%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}

.field__control[aria-invalid="true"] {
  border-color: #ff8a80;
}

.field__control[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px rgba(255, 138, 128, 0.2);
}

.field__error {
  display: none;
  color: #ffb4ac;
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
}

.field__error.is-shown {
  display: block;
}

/* Radio group */
.choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.choice {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: 48px;
  padding: var(--space-2) var(--space-5);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-pill);
  background-color: var(--c-void);
  color: var(--c-text-mute);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out);
}

.choice:hover {
  border-color: var(--c-border-strong);
  color: var(--c-text);
  background-color: var(--c-surface-2);
}

.choice input {
  position: absolute;
  opacity: 0;
  inline-size: 1px;
  block-size: 1px;
}

.choice__dot {
  inline-size: 16px;
  block-size: 16px;
  flex: none;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-pill);
  transition: border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.choice:has(input:checked) {
  border-color: var(--c-lime);
  background-color: var(--c-lime-soft);
  color: var(--c-text);
}

.choice:has(input:checked) .choice__dot {
  border-color: var(--c-lime);
  box-shadow: inset 0 0 0 4px var(--c-lime);
}

/* The visually hidden radio still needs a visible keyboard indicator. */
.choice:has(input:focus-visible) {
  outline: 3px solid var(--c-focus);
  outline-offset: 3px;
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin-block-start: var(--space-8);
}

.form-fineprint {
  color: var(--c-text-faint);
  font-size: var(--fs-xs);
  line-height: var(--lh-normal);
  max-inline-size: 52ch;
}

/* Status region. One element, three tones, driven by a data attribute so the
   live region is never torn down and re-announced. */
.form-status {
  margin-block-start: var(--space-6);
  padding: var(--space-5);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--c-void);
  color: var(--c-text-mute);
  line-height: var(--lh-relaxed);
}

.form-status:empty {
  display: none;
}

.form-status strong {
  display: block;
  margin-block-end: var(--space-2);
  color: var(--c-text);
  font-size: var(--fs-lg);
}

.form-status a {
  color: var(--c-lime);
}

.form-status[data-tone="success"] {
  border-color: rgba(159, 232, 112, 0.45);
  background-color: var(--c-lime-soft);
}

.form-status[data-tone="error"] {
  border-color: rgba(255, 138, 128, 0.5);
}

.form-status__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-block-start: var(--space-5);
}

/* Aside beside the form */
.quote-aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.aside-card {
  padding: var(--space-6);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  background-color: var(--c-surface);
}

.aside-card__title {
  margin-block-end: var(--space-4);
  font-size: var(--fs-lg);
}

.steps-min {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.steps-min li {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: var(--space-3);
  align-items: start;
  color: var(--c-text-mute);
  line-height: var(--lh-relaxed);
}

.steps-min li::before {
  counter-increment: step;
  content: counter(step);
  display: grid;
  place-items: center;
  inline-size: 28px;
  block-size: 28px;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-pill);
  color: var(--c-lime);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
}

/* --------------------------------------------------------------------------
   Portrait split frames
   The real tripod photography is 3:4. Uncapped, a portrait image would tower
   over the text column it sits beside, so portrait frames get a width ceiling
   and center themselves in the media column.
   -------------------------------------------------------------------------- */
.split__frame--portrait {
  max-inline-size: 440px;
  margin-inline: auto;
}

/* --------------------------------------------------------------------------
   Seasons strip — three real seasonal installs (permanent-lighting.html)
   -------------------------------------------------------------------------- */
.seasons {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
  margin: var(--space-12) 0 0;
  padding: 0;
  list-style: none;
}

.seasons__item {
  aspect-ratio: 3 / 4;
}

.seasons__item .seasons__label {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  padding: var(--space-6) var(--space-4) var(--space-3);
  background: linear-gradient(to top, rgba(4, 7, 5, 0.82), transparent);
  color: var(--c-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}

.seasons__note {
  margin-block-start: var(--space-3);
  color: var(--c-text-faint);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  text-align: center;
}

@media (min-width: 600px) {
  .seasons {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* --------------------------------------------------------------------------
   Spec ledger — confirmed product facts (permanent-lighting.html)
   Hairline rows in the same voice as the homepage benefits ledger.
   -------------------------------------------------------------------------- */
.specs {
  display: grid;
  gap: var(--space-6) var(--space-8);
  grid-template-columns: 1fr;
  margin: 0 0 var(--space-16);
  padding: 0;
  list-style: none;
}

.spec {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding-block-start: var(--space-3);
  border-block-start: 1px solid var(--c-border);
}

.spec strong {
  color: var(--c-text);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight, -0.01em);
}

.spec span {
  color: var(--c-text-mute);
  font-size: var(--fs-sm);
}

@media (min-width: 600px) {
  .specs {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 900px) {
  .specs {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* --------------------------------------------------------------------------
   Reduced motion
   The transforms above are hover polish, not information, so they simply stop.
   base.css already collapses transition durations globally.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .usecase:hover,
  .value:hover,
  .tile__btn:hover,
  .split__frame:hover {
    transform: none;
  }

  .tile__btn:hover .tile__media > img {
    scale: 1;
  }
}
