/* ============================================================
   HOUSE CIRCUIT — CORE
   Tokens, base, type, buttons, header, menu, footer, reveals.
   Concept "Live Wire": one signal line runs through the site; each
   section is a stop on the circuit, labelled by its title.
============================================================ */

/* Fonts, self-hosted (latin subsets from Google Fonts, SIL OFL 1.1), so
   they load from this server on the first round trip instead of after
   two more connections. Big Shoulders Display and Instrument Sans are
   variable (one file covers every weight). The two critical files are
   preloaded in base.html with these exact URLs: keep ?v= in step there,
   and bump it if a file changes. */
@font-face {
  font-family: 'Big Shoulders Display';
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/big-shoulders-display-latin.woff2?v=24') format('woff2');
}
@font-face {
  font-family: 'Instrument Sans';
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/instrument-sans-latin.woff2?v=4') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-400-latin.woff2?v=20') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Only fetched for text that needs it (The Name's phonetic spellings). */
@font-face {
  font-family: 'IBM Plex Mono';
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-400-latin-ext.woff2?v=20') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-500-latin.woff2?v=20') format('woff2');
}

:root {
  /* Surfaces */
  --ink: #050706;
  --ink-2: #0a0d0b;
  --ink-3: #111612;
  --ink-4: #182019;
  --line: rgba(214, 255, 226, 0.1);
  --line-2: rgba(214, 255, 226, 0.2);

  /* Text */
  --text: #e9f3ec;
  --text-2: #a7bbae;
  --text-3: #6f8577;

  /* Signal (brand) + status accent */
  --signal: #39ff7f;
  --signal-ink: #021408;
  --signal-glow: rgba(57, 255, 127, 0.45);
  --signal-soft: rgba(57, 255, 127, 0.1);
  --amber: #ffb627;
  --danger: #ff5a5f;

  /* Type */
  --f-display: 'Big Shoulders Display', 'Arial Narrow', Impact, sans-serif;
  --f-body: 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --f-mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Consolas, monospace;

  --fs-label: 12px;
  --fs-small: 14px;
  --fs-body: clamp(16px, 0.35vw + 14.6px, 18px);
  --fs-lead: clamp(19px, 0.8vw + 13px, 26px);
  --fs-h3: clamp(26px, 1.6vw + 14px, 40px);
  --fs-display: clamp(48px, min(6.6vw, 11.5svh), 124px);

  /* Layout */
  --gutter: clamp(18px, 4vw, 64px);
  --maxw: 1480px;
  --header-h: 68px;
  --radius: 2px;

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --t-fast: 160ms;
  --t-mid: 320ms;
  --t-slow: 900ms;
}

/* ------------------------------------------------------------
   BASE
------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
/* `hidden` always wins over a component's own display (the dossier's photo
   block and the lightbox arrows set display: grid/flex, which used to keep
   them on screen while hidden). */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + 16px);
  background: var(--ink);
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--ink);
  color: var(--text-2);
  font-family: var(--f-body);
  font-size: var(--fs-body);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;   /* fallback: browsers without clip (Safari < 16) */
  overflow-x: clip;
}

h1, h2, h3, h4, p, ul, ol, figure, blockquote, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, video, svg, canvas { display: block; max-width: 100%; }
img { height: auto; }
button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--signal); color: var(--signal-ink); }

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
}

html.is-locked { overflow: hidden; }

.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  left: 16px;
  top: -60px;
  z-index: 200;
  padding: 10px 16px;
  background: var(--signal);
  color: var(--signal-ink);
  font-weight: 600;
  transition: top var(--t-fast);
}
.skip-link:focus { top: 12px; }

.mono { font-family: var(--f-mono); }

/* ------------------------------------------------------------
   TYPE
------------------------------------------------------------ */
.display {
  font-family: var(--f-display);
  font-weight: 900;
  font-size: var(--fs-display);
  line-height: 0.94;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  color: var(--text);
}

.h3 {
  font-family: var(--f-display);
  font-weight: 800;
  font-size: var(--fs-h3);
  line-height: 1.05;
  text-transform: uppercase;
  color: var(--text);
}

.hl { color: var(--signal); }

.lead {
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--text);
  letter-spacing: -0.01em;
}

/* Mono data label: section labels, status chips, meta rows */
.label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--f-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-3);
}

.dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 10px var(--signal-glow);
  flex-shrink: 0;
}
.dot--live { background: var(--amber); box-shadow: 0 0 10px rgba(255, 182, 39, 0.6); }
@media (prefers-reduced-motion: no-preference) {
  .dot--pulse { animation: dot-pulse 1.8s ease-in-out infinite; }
}
@keyframes dot-pulse {
  50% { opacity: 0.35; }
}
/* Endless animations pause while off screen (site.js adds .is-offscreen
   to the marquees and pulsing dots): a running animation makes the
   browser restyle every frame, even where nobody can see it. */
.is-offscreen,
.is-offscreen * { animation-play-state: paused !important; }

/* ------------------------------------------------------------
   LAYOUT HELPERS
------------------------------------------------------------ */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  position: relative;
  padding-block: clamp(64px, 10vh, 120px);
}

/* Section head: numbered stop + display title (+ optional aside) */
.sec-head {
  display: grid;
  gap: clamp(12px, 1.8vh, 20px);
  margin-bottom: clamp(28px, 4.5vh, 52px);
}
@media (min-width: 960px) {
  .sec-head--split {
    grid-template-columns: minmax(0, 1fr) minmax(280px, 0.5fr);
    align-items: end;
    column-gap: clamp(32px, 5vw, 96px);
  }
}
.sec-head .sec-aside { max-width: 44ch; }

/* Section label: a short signal line, then the title ("—— Archive"). */
.stop {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-family: var(--f-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-2);
}
.stop::before {
  content: '';
  width: clamp(24px, 3vw, 48px);
  height: 1px;
  background: var(--signal);
  box-shadow: 0 0 8px var(--signal-glow);
}

/* ------------------------------------------------------------
   BUTTONS
------------------------------------------------------------ */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 50px;
  padding: 0 24px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: none;
  font-family: var(--f-mono);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  isolation: isolate;
  overflow: hidden;
  transition:
    color var(--t-mid) var(--ease-out),
    border-color var(--t-mid) var(--ease-out),
    background-color var(--t-mid) var(--ease-out),
    box-shadow var(--t-mid) var(--ease-out),
    transform var(--t-fast) var(--ease-out);
}
.btn:active { transform: translateY(1px); }
.btn-sm { min-height: 40px; padding: 0 16px; font-size: 12px; }

/* Signal: solid green; hover wipes in a brighter band from the left. */
.btn-signal {
  background: var(--signal);
  color: var(--signal-ink);
  box-shadow: 0 0 0 0 var(--signal-glow);
}
.btn-signal::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: #b6ffd0;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-mid) var(--ease-out);
}
.btn-signal:hover { box-shadow: 0 0 28px var(--signal-glow); }
.btn-signal:hover::before { transform: scaleX(1); }

.btn-ghost {
  border-color: var(--line-2);
  color: var(--text);
}
.btn-ghost:hover {
  border-color: var(--signal);
  color: var(--signal);
  background: var(--signal-soft);
}

/* Very narrow screens: long labels wrap instead of overflowing. */
@media (max-width: 420px) {
  .btn {
    max-width: 100%;
    white-space: normal;
    text-align: center;
    line-height: 1.3;
    padding-block: 10px;
  }
}

.btn[disabled],
.btn[aria-busy="true"] { opacity: 0.6; pointer-events: none; }

/* Inline text link with a drawn underline */
/* A real underline (not a 1px background strip, which Firefox can snap
   away when the link's height lands on a fractional pixel). */
.link {
  color: var(--text);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.32em;
  transition: color var(--t-fast);
}
.link:hover { color: var(--signal); }

/* ------------------------------------------------------------
   HEADER
------------------------------------------------------------ */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-inline: var(--gutter);
  border-bottom: 1px solid transparent;
  transition:
    transform var(--t-mid) var(--ease-out),
    background-color var(--t-mid) var(--ease-out),
    border-color var(--t-mid) var(--ease-out);
}
.site-header.is-scrolled {
  background: rgba(5, 7, 6, 0.94);
  border-bottom-color: var(--line);
}
/* The glass blur only where it's cheap (desktop GPUs with a mouse);
   phones get the near-solid bar, which scrolls smoother. */
@media (hover: hover) and (pointer: fine) {
  .site-header.is-scrolled {
    background: rgba(5, 7, 6, 0.82);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
    backdrop-filter: blur(14px) saturate(1.2);
  }
}
.site-header.is-hidden { transform: translateY(-100%); }
html.menu-open .site-header { transform: none; background: transparent; border-color: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  color: var(--text);
}
.brand img { width: 48px; height: auto; }
.brand-name {
  font-family: var(--f-display);
  font-weight: 800;
  font-size: 21px;
  line-height: 1;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}
.brand-name em {
  font-style: normal;
  color: var(--signal);
}

.site-nav { display: none; }
.site-nav ul { display: flex; gap: clamp(20px, 3vw, 44px); }
.site-nav a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--f-mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-2);
  transition: color var(--t-fast);
}
.site-nav a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 8px;
  height: 1px;
  background: var(--signal);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--t-mid) var(--ease-out);
}
.site-nav a:hover { color: var(--text); }
.site-nav a:hover::after,
.site-nav a[aria-current="page"]::after { transform: scaleX(1); transform-origin: left; }
.site-nav a[aria-current="page"] { color: var(--signal); }

.header-actions { display: flex; align-items: center; gap: 10px; }
.header-news { display: none; }

/* Instagram / Facebook: just the line logos (no frame), on a 44px tap
   target, lighting signal green with a soft glow on hover and focus. */
.social-btn {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--radius);
  color: var(--text);
  transition: color var(--t-fast), filter var(--t-fast);
}
.social-btn svg {
  width: 22px;
  height: 22px;
  filter: drop-shadow(0 1px 6px rgba(0, 0, 0, 0.7));
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.social-btn .social-dot { fill: currentColor; stroke: none; }
.social-btn:hover,
.social-btn:focus-visible { color: var(--signal); }
.social-btn:hover svg,
.social-btn:focus-visible svg { filter: drop-shadow(0 0 8px var(--signal-glow)); }

.menu-toggle {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  background: rgba(5, 7, 6, 0.6);
}
.menu-toggle-bars,
.menu-toggle-bars::before,
.menu-toggle-bars::after {
  display: block;
  width: 18px;
  height: 1.5px;
  background: var(--text);
  transition: transform var(--t-mid) var(--ease-out), opacity var(--t-fast);
}
.menu-toggle-bars { position: relative; }
.menu-toggle-bars::before,
.menu-toggle-bars::after { content: ''; position: absolute; left: 0; }
.menu-toggle-bars::before { transform: translateY(-6px); }
.menu-toggle-bars::after { transform: translateY(6px); }
html.menu-open .menu-toggle-bars { background: transparent; }
html.menu-open .menu-toggle-bars::before { transform: rotate(45deg); background: var(--signal); }
html.menu-open .menu-toggle-bars::after { transform: rotate(-45deg); background: var(--signal); }

@media (min-width: 900px) {
  .site-nav { display: block; }
  .menu-toggle { display: none; }
  .header-news { display: inline-flex; }
}
/* Phones and tablets: a bigger mark (60px, inside the 68px bar). The
   mark never shrinks; where the wordmark would crowd it (under 480px)
   the logo stands alone, since it reads House Circuit itself. */
.brand picture { flex: none; }
@media (max-width: 899px) {
  .brand { gap: 10px; }
  .brand img { width: 60px; }
}
@media (max-width: 479px) {
  .brand-name { display: none; }
}
.header-actions .social-btn + .social-btn { margin-left: -8px; }   /* the logos sit as a pair */
@media (max-width: 359px) {
  .header-actions { gap: 0; }
  .header-actions .social-btn + .social-btn { margin-left: 0; }
  .social-btn { width: 40px; }
}

/* ------------------------------------------------------------
   MOBILE MENU
------------------------------------------------------------ */
.menu-panel {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 32px;
  padding: calc(var(--header-h) + 5vh) var(--gutter) max(32px, env(safe-area-inset-bottom));
  background:
    radial-gradient(120% 60% at 100% 0%, rgba(57, 255, 127, 0.1), transparent 60%),
    var(--ink);
  clip-path: inset(0 0 100% 0);
  visibility: hidden;
  transition:
    clip-path 0.6s var(--ease-in-out),
    visibility 0s linear 0.6s;
}
html.menu-open .menu-panel {
  clip-path: inset(0 0 0 0);
  visibility: visible;
  transition: clip-path 0.6s var(--ease-in-out), visibility 0s;
}

.menu-links { display: grid; gap: 4px; }
.menu-links a {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding-block: 6px;
  font-family: var(--f-display);
  font-weight: 900;
  font-size: clamp(52px, 15vw, 104px);
  line-height: 1;
  text-transform: uppercase;
  color: var(--text);
}
.menu-links a[aria-current="page"] { color: var(--signal); }
.menu-foot { display: grid; gap: 12px; }

@media (min-width: 900px) {
  .menu-panel { display: none; }
}

/* ------------------------------------------------------------
   MARQUEE TAPE
------------------------------------------------------------ */
.tape {
  position: relative;
  overflow: hidden;
  background: var(--signal);
  color: var(--signal-ink);
  border-block: 1px solid var(--signal);
}
.tape-track {
  display: flex;
  width: max-content;
}
.tape-item {
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 14px 14px;
  font-family: var(--f-display);
  font-weight: 900;
  font-size: clamp(22px, 2.4vw, 36px);
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}
.tape-item::after {
  content: '';
  width: 12px;
  height: 12px;
  border: 2px solid currentColor;
  transform: rotate(45deg);
}
@media (prefers-reduced-motion: no-preference) {
  .tape-track { animation: tape 38s linear infinite; }
}
@keyframes tape {
  to { transform: translate3d(-50%, 0, 0); }
}

/* ------------------------------------------------------------
   FOOTER
------------------------------------------------------------ */
.site-footer {
  position: relative;
  border-top: 1px solid var(--line);
  padding: clamp(64px, 10vh, 120px) var(--gutter) 28px;
  background: var(--ink);
  overflow: hidden;
}
.footer-top {
  display: grid;
  gap: 48px;
  max-width: var(--maxw);
  margin-inline: auto;
}
@media (min-width: 820px) {
  .footer-top { grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.6fr) minmax(0, 0.6fr); }
}
.footer-cta { display: grid; gap: 16px; justify-items: start; max-width: 460px; }
.footer-lead { color: var(--text); font-size: var(--fs-lead); line-height: 1.5; }
.footer-nav ul,
.footer-social ul { display: grid; gap: 6px; margin-top: 16px; }
.footer-nav a,
.footer-social a {
  display: inline-flex;
  min-height: 36px;
  align-items: center;
  color: var(--text);
  transition: color var(--t-fast);
}
.footer-nav a:hover,
.footer-social a:hover { color: var(--signal); }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px 24px;
  max-width: var(--maxw);
  margin: clamp(48px, 8vh, 88px) auto 0;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  font-size: var(--fs-small);
  color: var(--text-3);
}
.footer-bottom a:hover { color: var(--signal); }

/* ------------------------------------------------------------
   FLASH MESSAGES
------------------------------------------------------------ */
.flash-stack {
  position: fixed;
  z-index: 150;
  right: var(--gutter);
  top: calc(var(--header-h) + 12px);
  display: grid;
  gap: 10px;
  max-width: min(440px, calc(100vw - 2 * var(--gutter)));
}
.flash {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--line-2);
  border-left: 3px solid var(--signal);
  background: rgba(10, 13, 11, 0.96);
  color: var(--text);
  font-size: var(--fs-small);
}
.flash-error { border-left-color: var(--danger); }
.flash-close {
  margin-left: auto;
  border: 0;
  background: none;
  color: var(--text-3);
  min-width: 28px;
  min-height: 28px;
}

/* ------------------------------------------------------------
   REVEALS — [data-reveal] (site.js adds .is-in by section: see
   REVEAL_AT in site.js). Hidden states only exist under
   html.motion, so no-JS / reduced motion / failed boot = visible.
   Opacity (never visibility) keeps unrevealed content focusable.
------------------------------------------------------------ */
.motion [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 32px, 0);
  transition:
    opacity 0.9s var(--ease-out) var(--d, 0s),
    transform 1.1s var(--ease-out) var(--d, 0s),
    clip-path 1.1s var(--ease-out) var(--d, 0s);
}
.motion [data-reveal="fade"] { transform: none; }
.motion [data-reveal="left"] { transform: translate3d(-48px, 0, 0); }
.motion [data-reveal="rise"] { transform: translate3d(0, 64px, 0); }
.motion [data-reveal="clip"] {
  transform: none;
  clip-path: inset(0 0 100% 0);
}
.motion [data-reveal="wipe"] {
  transform: none;
  clip-path: inset(0 100% 0 0);
}
.motion [data-reveal].is-in {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
}

/* Line-by-line headline reveal: each .line > span slides up. */
.split .line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.04em;
  margin-bottom: -0.04em;
}
.split .line > span { display: block; }
.motion .split[data-reveal] { opacity: 1; transform: none; }
.motion .split[data-reveal] .line > span {
  transform: translate3d(0, 105%, 0);
  transition: transform 1.1s var(--ease-out);
  transition-delay: calc(var(--d, 0s) + var(--i, 0) * 0.09s);
}
.motion .split[data-reveal].is-in .line > span { transform: none; }

/* Browsers without small-viewport units (Safari < 15.4, Chrome < 108):
   the svh sizes again in vh, so nothing collapses or shrinks to the
   body size (home.css and photos.css carry their own). */
@supports not (height: 1svh) {
  :root { --fs-display: clamp(48px, min(6.6vw, 11.5vh), 124px); }
}

/* ------------------------------------------------------------
   LARGE SCREENS (1440p monitors, 16:10 desktops, ultrawides): the
   type, spacing and page width scale up ~1.3x so the page fills
   the screen instead of floating small in the middle.
------------------------------------------------------------ */
@media (min-width: 1800px) and (min-height: 1100px) {
  :root {
    --fs-label: 14px;
    --fs-small: 17px;
    --fs-body: 21px;
    --fs-lead: 31px;
    --fs-h3: 50px;
    --fs-display: clamp(48px, min(6.6vw, 11.5svh), 168px);
    --gutter: 88px;
    --maxw: 2100px;
    --header-h: 84px;
  }
  .btn { min-height: 60px; padding: 0 32px; font-size: 15px; }
  .btn-sm { min-height: 48px; padding: 0 20px; font-size: 14px; }
  .brand img { width: 60px; }
  .brand-name { font-size: 26px; }
  .site-nav a { font-size: 14px; }
}
