/* site.css — per-site layout and components, built FROM tokens.
   MegaGlitch Computer Repair, Ogden UT. brief.md §5 (split-hero archetype),
   §10 (motion). HARD RULE (house-tech-spec §3): no raw hex, no px/rem size
   literals, no font-name literals. Tokens only. Escape hatches: house
   breakpoints (48em/64em) and an explicit `@allow-literal: reason` comment.
*/

/* --- Layout primitives -----------------------------------------------------
   The brief's own composition (reference/index.html) applies inline padding
   DIRECTLY to .hero/.section/.site-header/.site-footer — a flat two-step
   20px/56px pair (brief §4.1), never a nested max-width `.container` box
   below 90rem. `.container` survives here only for the house preview-only
   chrome (the expiry bar's own markup, @preview:expiry), which is not a
   brief-governed composition. */

.container {
  width: 100%;
  max-width: var(--layout-container);
  margin-inline: auto;
  padding-inline: var(--layout-gutter);
}

/* --section-gap is the only inter-section spacing value (design-rules §7.1). */
.section {
  padding-block: var(--section-gap);
  padding-inline: var(--content-padding-inline);
}

/* Beyond-1440 content cap (brief §5.8): a single added rule inside the
   existing ≥90rem breakpoint, not a new one — a no-op at 1440-1599px (the
   viewport is already <= 90rem) and adds equal side margin from 1600px up,
   repeating the 1440 composition rather than stretching the hero's art box
   or the trust index's three columns past their own stated caps. */
@media (min-width: 90em) {
  .hero,
  .section,
  .site-header,
  .site-footer {
    max-inline-size: var(--content-cap);
    margin-inline: auto;
  }
}

.measure {
  max-width: var(--layout-measure);
}

/* --- Header — brand only, no nav, no call control (brief §5.2) ------------
   This business has no tel: to place and no second nav target on a
   one-pager with no services section, no reviews, no FAQ. */

/* Single child (the brand link only, brief §5.2) — no flex needed. Flexing
   would blockify the anchor (CSS Display §2.7), which removes it from
   render-audit's "inline text link, sized by its line" a11y/touch exemption
   and forces a 44px tap-target floor that would break the brief's own exact
   52.2px header-height arithmetic (§4.1). Padding + line-height alone centre
   the one line without flex. */
.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-header);
  min-height: var(--header-min-h);
  box-sizing: border-box;
  padding-block: var(--space-sm);
  padding-inline: var(--content-padding-inline);
  /* Matches the brand link's own line-height so the line box's "strut" (the
     block's inherited line-height, not just the inline content's own) does
     not inflate the header past the brief's exact 52.2px figure (§4.1). */
  line-height: var(--leading-snug);
  border-bottom: var(--border-hairline) var(--border-style) var(--color-border);
  background-color: var(--color-bg);
}

.site-header__brand {
  /* display: inline (the anchor's own UA default, left unset) — brief §5.2's
     header has only this one line to fit and the brand measures comfortably
     inside its budget at 320px (§5.2), so no truncation device is needed;
     white-space keeps it from ever wrapping to a second line, which is what
     the header's own fixed height actually depends on. */
  white-space: nowrap;
  font-family: var(--font-body);
  font-size: var(--text-body);
  font-weight: var(--font-weight-body-strong);
  line-height: var(--leading-snug);
  text-decoration: none;
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
}

/* --- Buttons --- two roles, no more; radius/weight/colour come from tokens.
   --control-h (brief §4.3, 52px) sizes the page's own content buttons only
   (.btn--primary, .btn--quiet) — never .btn--buy, which is preview-only
   house chrome (skeleton/css/preview.css) governed by the house 44px
   touch-target floor (base.css), not this brief's arithmetic. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding-inline: var(--space-md);
  border: var(--border-hairline) var(--border-style) transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-weight: var(--font-weight-body-strong);
  line-height: 1;
  text-align: center;
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}

.btn--primary {
  min-height: var(--control-h);
  background-color: var(--color-accent);
  color: var(--color-accent-ink);
}

.btn--quiet {
  min-height: var(--control-h);
  border-color: var(--color-border-strong);
  color: var(--color-ink);
}

/* --- HERO — split-hero archetype (brief §5.1, §5.3, §5.5) -----------------
   DOM order: eyebrow, h1, primary CTA (inside .copy), art, lead — matching
   house order exactly (design-rules §7.2 rule 1). Below 48rem: single
   column, stacked. From 48rem: minmax(0,5fr) minmax(0,6fr), copy in row 1,
   art spanning both rows, lead in row 2. The hero is never revealed — it is
   the LCP element, at rest on first paint (brief §10). */

.hero {
  padding: var(--hero-padding-top) var(--content-padding-inline) var(--hero-padding-bottom);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--hero-row-gap);
}

.hero > * {
  align-self: start;
  min-width: 0;
}

.hero .eyebrow {
  margin: 0 0 var(--space-xs);
  font-family: var(--font-body);
  font-size: var(--text-small);
  line-height: var(--leading-eyebrow);
  font-weight: var(--font-weight-body-strong);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-accent);
}

.hero h1 {
  margin: 0 0 var(--space-sm);
  font-family: var(--font-display);
  font-size: var(--text-hero);
  font-weight: var(--font-weight-display);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
}

.hero h1 em {
  font-family: var(--font-emphasis);
  font-style: italic;
  color: var(--color-accent);
}

.hero .lead {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-lead);
  line-height: var(--leading-body);
  color: var(--color-ink-muted);
  max-width: var(--lead-measure-mid);
}

/* The art box: a framed 10:7 circuit-trace illustration. Two small overlay
   elements carry the signature ambient loops (brief §10) — never on the art
   box itself, never on an element whose position comes from a transform
   attribute. No text node sits over the art at any width (brief §2.2). */
.art {
  position: relative;
  background-color: var(--color-surface);
  aspect-ratio: var(--art-aspect);
  max-block-size: var(--art-cap-mobile);
  overflow: hidden;
  border-radius: var(--radius-sm);
}

.art picture,
.art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.art__glow {
  position: absolute;
  border-radius: var(--radius-sm);
  pointer-events: none;
}

/* Solder-point highlight: an 8.4s independent opacity loop over the glow's
   own frame position (brief §7.3: roughly x 55-62%, y 35-42%). */
.art__glow--solder {
  inset-inline-start: 54%;
  inset-block-start: 33%;
  inline-size: 14%;
  block-size: 20%;
  background: radial-gradient(circle, var(--color-accent-bright) 0%, transparent 70%);
  animation: solder-glint var(--duration-solder-glint) var(--ease-in-out) infinite;
}

/* Trace far-end highlight: a second, non-synchronised 6.6s loop. */
.art__glow--trace {
  inset-inline-start: 38%;
  inset-block-start: 44%;
  inline-size: 18%;
  block-size: 14%;
  background: radial-gradient(ellipse, var(--color-accent-bright) 0%, transparent 75%);
  animation: trace-glint var(--duration-trace-glint) var(--ease-in-out) infinite;
}

@keyframes solder-glint {
  0%, 100% { opacity: .35; }
  50% { opacity: 1; }
}

@keyframes trace-glint {
  0%, 100% { opacity: .25; transform: translateX(0); }
  50% { opacity: .8; transform: translateX(var(--trace-glint-shift)); }
}

@media (prefers-reduced-motion: reduce) {
  .art__glow--solder,
  .art__glow--trace {
    animation: none;
    opacity: .85;
  }
}

@media (min-width: 48em) {
  .hero {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    column-gap: var(--hero-column-gap-mid);
    row-gap: var(--hero-row-gap);
  }

  .hero .copy {
    grid-column: 1;
    grid-row: 1;
    max-width: var(--copy-measure-mid);
  }

  .hero .art {
    grid-column: 2;
    grid-row: 1 / span 2;
    max-block-size: none;
  }

  .hero .lead {
    grid-column: 1;
    grid-row: 2;
  }
}

@media (min-width: 90em) {
  .hero,
  .section,
  .site-header,
  .site-footer {
    padding-inline: var(--content-padding-inline-wide);
  }

  .hero {
    column-gap: var(--hero-column-gap-wide);
  }

  .hero .art {
    inline-size: min(var(--art-cap-desktop), 100%);
    justify-self: end;
  }

  .hero .copy {
    max-width: var(--copy-measure-wide);
  }

  .hero .lead {
    max-width: var(--lead-measure-wide);
  }
}

/* --- TRUST INDEX — "What we can tell you" (brief §5.4 section 2, §5.5) ---
   Single column with a top-rule between rows below 90rem; from 90rem,
   3 columns with a left accent rule. Numbered rows (01/02/03) are the
   page's only enumeration. */

.index-section h2 {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--text-h2);
  font-weight: var(--font-weight-display);
  line-height: var(--leading-snug);
  color: var(--color-ink);
}

.index-section .sub {
  margin: 0 0 var(--space-lg);
  font-family: var(--font-body);
  font-size: var(--text-body);
  color: var(--color-ink-muted);
  max-width: var(--index-sub-measure);
}

.index-row {
  border-top: var(--border-hairline) var(--border-style) var(--color-border);
  padding-block: var(--space-md);
  display: grid;
  grid-template-columns: var(--index-num-col) 1fr;
  gap: var(--space-sm);
}

.index-row:last-child {
  border-bottom: var(--border-hairline) var(--border-style) var(--color-border);
}

.index-row .num {
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: var(--font-weight-display);
  line-height: var(--leading-body);
  color: var(--color-accent);
}

.index-row .txt b {
  display: block;
  font-family: var(--font-body);
  font-size: var(--text-body);
  font-weight: var(--font-weight-body-strong);
  line-height: var(--leading-snug);
  color: var(--color-ink);
}

.index-row .txt span {
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  color: var(--color-ink-muted);
}

@media (min-width: 90em) {
  .index-list {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    column-gap: var(--hero-column-gap-mid);
  }

  .index-row {
    border-top: none;
    border-left: var(--radius-sm) solid var(--color-accent);
    padding: var(--space-3xs) 0 var(--space-3xs) var(--space-md);
  }

  .index-row:last-child {
    border-bottom: none;
  }
}

/* --- REQUEST — the house form, a centred column at every width (brief §5.5
   section 3): with only three fields and no accompanying facts list, a
   2-column split would create an empty second column (the "void" rule). */

.request-wrap {
  max-width: var(--request-max);
  margin-inline: auto;
}

.request-wrap h2 {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--text-h2);
  font-weight: var(--font-weight-display);
  line-height: var(--leading-snug);
  color: var(--color-ink);
}

.request-wrap .sub {
  margin: 0 0 var(--space-lg);
  font-family: var(--font-body);
  font-size: var(--text-body);
  color: var(--color-ink-muted);
  max-width: var(--request-sub-measure);
}

/* --- Form --- one per site. POSTs to the endpoint constant in main.js. */

.form {
  display: grid;
  gap: var(--space-md);
}

.field {
  display: grid;
  gap: var(--space-3xs);
}

.field__label {
  font-family: var(--font-body);
  font-size: var(--text-small);
  font-weight: var(--font-weight-body-strong);
  color: var(--color-ink);
}

.field__control {
  width: 100%;
  min-height: var(--control-h-input);
  padding: var(--space-2xs) var(--space-xs);
  background-color: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-body);
  border: var(--border-hairline) var(--border-style) var(--color-border-strong);
  border-radius: var(--radius-sm);
}

textarea.field__control {
  min-height: var(--space-3xl);
  resize: vertical;
}

.field__hint {
  font-family: var(--font-body);
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

/* Honeypot: not display:none (some bots skip those). */
.form__trap {
  position: absolute;
  /* @allow-literal: off-canvas parking position, not a design value */
  left: -9999px;
  opacity: 0;
  pointer-events: none;
}

.form__status {
  font-family: var(--font-body);
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

.form__status[data-state='error'] {
  color: var(--color-ink);
  font-weight: var(--font-weight-body-strong);
}

/* The hero CTA and the request-section fields are the two reveal groups on
   this page (brief §10) — scroll-margin so the sticky stack never covers
   the target heading. */
#request {
  scroll-margin-block-start: var(--scroll-offset);
}

/* --- Footer ----------------------------------------------------------------
   Brand, service-area line, hours — left-aligned, no grid (brief §5.5
   section 4). No tel: line (dossier §8.2). */

.site-footer {
  padding-block: var(--space-xl);
  padding-inline: var(--content-padding-inline);
  border-top: var(--border-hairline) var(--border-style) var(--color-border);
  font-family: var(--font-body);
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

.site-footer__nap {
  font-style: normal;
  color: var(--color-ink);
}

.site-footer a {
  text-underline-offset: var(--space-3xs);
}
