/* ==========================================================================
   pcb.css — the electronics theme, as structure rather than wallpaper
   --------------------------------------------------------------------------
   Traces route between things that are actually related: down the work index
   as a bus, out to each project's via, and between sections. Vias mark nodes.
   Everything is hairline weight and low contrast — it should read as the
   substrate the content is mounted on, never as an illustration competing
   with it.

   NAMING NOTE — the copper colour is --copper, NOT --pad. It used to be
   --pad, which collided with the page gutter variable of the same name in
   style.css. This file loads second, so the gutter resolved to a hex colour
   and every `padding: 0 var(--pad)` in the layout was silently discarded.
   That was the missing-margin bug on mobile. Do not rename it back.
   ========================================================================== */

:root {
  --trace:      rgba(111,182,196,.34);
  --trace-dim:  rgba(111,182,196,.16);
  --trace-gold: rgba(201,164,92,.34);
  --copper:     #0A1420;
}

/* ---------------------------------------------------------------- vias ----
   A via is a plated hole: an outer ring, a dark barrel, a bright centre. */
.via {
  position: relative; flex: none;
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--copper);
  border: 1px solid var(--trace);
  display: grid; place-items: center;
}
.via::after {
  content: ''; width: 3px; height: 3px; border-radius: 50%;
  background: var(--trace); transition: background .4s var(--ease);
}
.via-gold { border-color: var(--trace-gold); }
.via-gold::after { background: var(--gold); }

/* --------------------------------------------------------- section rule --
   Section headings sit on a trace that runs out to the page edge and ends
   in a via — a net leaving the block. */
.sec-head { position: relative; }
.sec-rule { display: flex; align-items: center; gap: 0; margin-top: 22px; }
.sec-rule .ln { height: 1px; background: linear-gradient(90deg, var(--trace), var(--trace-dim) 60%, transparent); flex: 1; }
.sec-rule .via { margin-right: -1px; }

/* ---------------------------------------------------------- work bands --
   Alternating editorial bands joined by routed traces. The connector runs
   from the trailing edge of one band, across the page through a schematic
   component, into the leading edge of the next — so the eight projects read
   as one net rather than eight unrelated blocks.

   The bands carry title, one line, tags and a link. Nothing more: the case
   study is one click away and does the explaining. A home page that repeats
   the project page just makes the reader read everything twice. */
.index { position: relative; }

.band { position: relative; }
.band-in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4.2vw, 56px);
  align-items: center;
}
.band.flip .band-in { direction: rtl; }
.band.flip .band-in > * { direction: ltr; }

/* the first project is the flagship and gets more type weight */
.band-lead .band-title { font-size: clamp(28px, 4.6vw, 50px); }
.band-lead .band-sub   { font-size: clamp(15px, 1.9vw, 17.5px); }

.band-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.band-top .proj-num { font-size: clamp(18px, 2.4vw, 26px); }

.band-title { font-family: var(--serif); font-size: clamp(24px, 3.6vw, 40px); line-height: 1.08; margin: 14px 0 10px; }
.band-title a { transition: color .3s var(--ease); }
.band:hover .band-title a { color: var(--gold-hi); }
.band-sub { color: var(--fg-2); font-size: clamp(14px, 1.8vw, 16.5px); max-width: 44ch; }

.band-go { margin-top: clamp(18px, 2.6vw, 24px); }
.band-go svg { transition: transform .34s var(--ease); }
.band:hover .band-go svg { transform: translate(2px, -2px); }

/* media + the spec readout beneath it */
.band-media { position: relative; min-width: 0; }

/* UNIFORM CARDS.
   --------------------------------------------------------------------------
   Every card is the same size with the same padding on all four sides. That
   only holds if every image is the same shape, so the IMAGES are normalised
   rather than the frame: assets/img/cards/ holds one 1200x750 file per
   project, and the img fills the frame edge to edge.

   The previous version kept the frame at 16:10 and CONTAINed images whose
   source ratios ran 1.33 to 1.94. Every card came out the same size, but the
   gap around the picture did not — 17px at the sides on all of them, and
   anywhere from 27px to 41px top and bottom depending on the image. Uniform
   frames with non-uniform contents read as uneven padding, because the eye
   measures the picture, not the box.

   Nothing is lost to achieve this. Photographs are centre-cropped to 16:10,
   which costs very little at these ratios; diagrams and charts are padded
   OUTWARDS in their own border colour, so the extension is invisible and no
   axis label or state box is cut. See `cardImage` in js/content.js. */
.band-figure {
  position: relative; border-radius: 18px; overflow: hidden;
  aspect-ratio: 16 / 10;
  display: block;
  padding: clamp(10px, 1.4vw, 16px);
  background: var(--glass-bg);
  backdrop-filter: blur(20px) saturate(150%); -webkit-backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid var(--glass-edge);
  box-shadow: var(--glass-spec), var(--glass-glow), 0 18px 44px rgba(0,0,0,.4);
}
.band-figure img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block; border-radius: 10px;
  transition: transform 1.2s var(--ease-out);
}
/* Fallback for a project added without a matching 1200x750 card image: show
   the whole picture rather than cropping something important out of it. This
   card will not line up with the others — which is the reminder to make one. */
.band-figure-fit { display: grid; place-items: center; }
.band-figure-fit img {
  width: auto; height: auto; max-width: 100%; max-height: 100%;
  object-fit: contain;
}
.band:hover .band-figure img { transform: scale(1.035); }
/* corner pad on the frame, like a mounted board */
.band-figure::after {
  content: ''; position: absolute; right: 12px; top: 12px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--trace-dim);
}

/* THE readout — sits BELOW the frame, not over it. Once the image frame
   became glass, a glass readout laid on top was glass on glass: two
   translucent layers blurring each other instead of one clean surface. */
.readout {
  position: relative; z-index: 3;
  margin: clamp(10px, 1.4vw, 14px) 0 0;
  border-radius: 15px; padding: clamp(14px, 1.8vw, 19px) clamp(15px, 2vw, 22px);
  display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(10px, 1.4vw, 18px);
}
.readout::after {                      /* footprint pad */
  content: ''; position: absolute; right: 11px; bottom: 11px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--trace-dim);
}

/* ------------------------------------------------------------ connectors */
.conn-wrap { position: relative; height: clamp(84px, 10vw, 128px); margin: clamp(4px, 1vw, 10px) 0; }
.connector { position: absolute; inset: 0; color: var(--trace); }
.conn-line, .conn-sym { position: absolute; inset: 0; width: 100%; height: 100%; }
.conn-line { color: var(--trace-dim); }
.conn-sym  { color: var(--trace); }
.cv { fill: var(--copper); stroke: var(--trace); stroke-width: 1.2; }

/* ---------------------------------------------------------- stat panels --
   Glass. These were the most convincing liquid-glass surface on the page. */
.stat {
  position: relative; border-radius: 15px; padding: clamp(15px, 2.2vw, 22px);
  overflow: hidden;
}
.stat::before {                        /* specular top edge */
  content: ''; position: absolute; top: 0; left: 14%; right: 14%; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.32), transparent);
}
.stat::after {                         /* corner pad, like a component footprint */
  content: ''; position: absolute; right: 12px; bottom: 12px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--trace-dim);
}

/* -------------------------------------------------------------- bullets --
   List markers drawn as plated through-holes: an outer ring, the board
   colour inside, a bright centre. Fully defined here — style.css only
   supplies `position: relative` on the list item. */
.exp-pts li, .lead li { padding-left: 26px; }
.exp-pts li::before, .lead li::before {
  content: ''; position: absolute; left: 0; top: 7px;
  width: 11px; height: 11px;
  border-radius: 50%; background: var(--copper);
  border: 1px solid var(--trace);
}
.exp-pts li::after, .lead li::after {
  content: ''; position: absolute; left: 4px; top: 11px;
  width: 3px; height: 3px; border-radius: 50%; background: var(--trace);
}
/* a bullet that follows a divider sits lower by the padding amount */
.lead li + li::before { top: 20px; }
.lead li + li::after  { top: 24px; }

/* ------------------------------------------------------- timeline nodes --
   The experience track's nodes, drawn as vias so they match everything else. */
.exp::before {
  content: ''; position: absolute;
  left: calc(-1 * clamp(20px, 3vw, 36px) - 5px);
  top: calc(clamp(24px, 3.6vw, 40px) + 10px);
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--copper);
  border: 1px solid var(--trace-gold);
  box-shadow: 0 0 0 4px var(--ink);
}
.exp:first-child::before {
  border-color: var(--gold);
  box-shadow: 0 0 0 4px var(--ink), 0 0 14px rgba(201,164,92,.5);
}
.exp::after {                          /* branch off the track */
  content: ''; position: absolute;
  left: calc(-1 * clamp(20px, 3vw, 36px) + 6px);
  top: calc(clamp(24px, 3.6vw, 40px) + 15px);
  width: clamp(12px, 2vw, 22px); height: 1px; background: var(--trace-dim);
}

/* --------------------------------------------------------- case study ----
   Solder-mask style hairline around the hero shot, and a pad in the corner
   of each readout cell, so the page reads as one board. */
.case-hero { position: relative; }
.case-hero::after {
  content: ''; position: absolute; inset: 10px; pointer-events: none;
  border: 1px solid rgba(255,255,255,.06); border-radius: 12px;
}
.rd { position: relative; }
.rd::after {
  content: ''; position: absolute; top: 10px; right: 10px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--trace-dim);
}

/* -------------------------------------------------------------- responsive */
@media (max-width: 1200px) {
  /* four spec cells across a half-width column wraps the labels badly */
  .readout { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 880px) {
  /* bands stack, media first — and the connector becomes a short vertical
     run rather than a wide diagonal that would have nothing to cross */
  .band-in { grid-template-columns: 1fr; gap: 20px; }
  .band.flip .band-in { direction: ltr; }
  .band-media { order: -1; }

  /* The 16:10 frame is KEPT when stacked. Two things depend on it:
     every home-page image in this set is landscape between 1.33 and 1.94,
     so 1.6 wastes very little; and a fixed ratio reserves the box before a
     lazy image loads. Dropping it to `auto` collapsed each unloaded frame to
     its padding, and the page jumped as you scrolled. Only the padding
     tightens here. */
  .band-figure { padding: 12px; }

  .conn-wrap { height: 76px; }
  .conn-line, .conn-sym { display: none; }
  .conn-wrap::before {
    content: ''; position: absolute; left: 50%; top: 0; bottom: 0; width: 1px;
    background: linear-gradient(to bottom, transparent, var(--trace-dim), transparent);
  }
  .conn-wrap::after {
    content: ''; position: absolute; left: 50%; top: 50%;
    width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px;
    border-radius: 50%; background: var(--copper); border: 1px solid var(--trace);
  }
}

@media (max-width: 620px) {
  .band-top .proj-num { font-size: 17px; }
  .conn-wrap { height: 60px; }
}

@media (max-width: 420px) {
  .readout { grid-template-columns: 1fr 1fr; gap: 12px 10px; padding: 15px 16px; }
  .band-figure { padding: 10px; }
}
