/* halide — Anna Okafor. Round 2.
   Ground: her basement viewing wall, flat black cut with white.
   Type: one family, Courier Prime, because everything she labels is typed.
   Accent: the red china marker she circles keepers with.
   Tokens: ground #181512, panel #1f1b17, strip #0e0c0a, paper #ece5d8,
   pencil #a49a8c, marker #d4472e (graphics), marker text #e0653f. */

* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --ground: #181512;
  --panel: #1f1b17;
  --strip: #0e0c0a;
  --paper: #ece5d8;
  --pencil: #a49a8c;
  --marker: #d4472e;
  --marker-text: #e0653f;
  --rule: #322c26;
  /* vertical rhythm (editorial/portfolio genre, per spacing.md):
     tight 0 — captions and strips touch their frames;
     base 64px — the gallery walking beat between rolls;
     grand 120px = 1.875x base, spent twice: before the log (the star
     artifact) and before the prints (the ask). ITN 60/120 pattern. */
  --rhythm-tight: 0rem;
  --rhythm-base: 4rem;
  --rhythm-grand: clamp(5.5rem, 8.4vw, 7.5rem);
  --step-0: 0.9375rem;  /* 15px body */
  --step-1: 1.125rem;
  --step-2: 1.5rem;
  --step-3: 2.125rem;
  --step-4: 3rem;
}

/* ============================================================
   MOTION — two themes, named, repeated the whole way down.

   1. "the print coming up."  Anything that arrives on the page arrives the
      way an image arrives in the tray: ten pixels of rise, flat and grey
      first, then full density. Used on every enlarged frame, every print in
      the flat file, the ledger card, the sandwich board, each roll head.

   2. "the china marker."  Every red mark draws itself left to right, the
      way she circles a keeper on the sheet: a wipe across the stroke.
      Used on the keeper circles in all three strips, the circle on the
      ledger card, and the rule under the order line.

   Both run on scroll position, not on a timer, so nothing moves unless the
   reader moves. Both are off entirely under prefers-reduced-motion, and both
   sit inside @supports, so a browser without scroll timelines — or a page
   with the script dead — simply shows everything already developed and
   already circled. Nothing here is load-bearing.
   ============================================================ */
/* uses the independent `translate` property, not `transform`, so the rise
   composes with the rotation the ledger card and the sign board already carry
   instead of wiping it out. */
@keyframes develop {
  from { opacity: 0.28; filter: contrast(0.7) brightness(1.22) saturate(0.6); translate: 0 10px; }
  to   { opacity: 1;    filter: none;                                         translate: none; }
}
@keyframes marker {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 -3% 0 0); }
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .viewer .shot,
    .print-grid figure,
    .ledger-card,
    .board,
    .roll-head + .roll-note {
      animation: develop linear both;
      animation-timeline: view();
      animation-range: entry 4% cover 24%;
    }
    .frame.keeper .circle,
    .ledger-card .lc-circle,
    .order-cta svg {
      animation: marker linear both;
      animation-timeline: view();
      animation-range: entry 12% cover 22%;
    }
  }
}

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* texture as material: one grain surface over the whole near-black ground,
   which is also what lifts apparent contrast on the photographs. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 40;
  pointer-events: none;
  opacity: 0.055;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}

body {
  background: var(--ground);
  color: var(--paper);
  font-family: "Courier Prime", "Courier New", Courier, monospace;
  font-size: var(--step-0);
  line-height: 1.65;
}

[id] { scroll-margin-top: 5.5rem; }

img { max-width: 100%; display: block; }

a { color: var(--paper); text-decoration: underline; text-underline-offset: 3px; transition: color 0.15s ease; }
a:hover { color: var(--marker-text); }

:focus-visible {
  outline: 2px solid var(--paper);
  outline-offset: 3px;
}

.wrap { max-width: 68rem; margin: 0 auto; padding: 0 1.25rem; }

/* ---------- for-sale banner ---------- */
.forsale {
  background: var(--paper);
  color: #241f1a;
  font-size: 0.8125rem;
  padding: 0.5rem 1.25rem;
  text-align: center;
}
.forsale a { color: #241f1a; }
.forsale a:hover { color: #8c2f1d; }

/* ---------- header ---------- */
.site-head {
  border-bottom: 1px solid var(--rule);
  padding: 1.1rem 0;
}
.site-head .wrap {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.stamp {
  font-weight: 700;
  font-size: 0.9375rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1.5px solid var(--paper);
  padding: 0.2rem 0.55rem;
  transform: rotate(-0.6deg);
  display: inline-block;
}
.stamp { transition: border-color 0.15s ease; }
.stamp:hover { color: var(--paper); border-color: var(--marker-text); }
.site-head nav { display: flex; gap: 1.4rem; flex-wrap: wrap; font-size: 0.875rem; }
.site-head nav a { text-decoration: none; }
.site-head nav a:hover { text-decoration: underline; }
.head-phone { font-weight: 700; }

/* ---------- opening ---------- */
/* hero -> first roll is glued: 24px against a 64px base (0.375x),
   the full-bleed keeper starts almost immediately */
.open { padding: 1.75rem 0 1.5rem; }
.open h1 {
  font-size: clamp(1.5rem, 4.2vw, var(--step-3));
  font-weight: 400;
  line-height: 1.35;
  max-width: 56rem;
}
.open h1 .name { font-weight: 700; }
/* the log section — GRAND pause before it (rolls end at half-base 2rem,
   log opens at grand minus that): the un-moveable artifact gets the silence */
.log {
  padding: calc(var(--rhythm-grand) - var(--rhythm-base) / 2) 0 calc(var(--rhythm-base) / 2);
  border-top: 1px solid var(--rule);
}
.log h2 { font-size: var(--step-2); font-weight: 400; margin-bottom: 0.75rem; }
.log-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: 3.5rem;
  align-items: center;
}
.log-copy p { max-width: 34rem; margin-bottom: 1rem; }
.log-copy .pencil { color: var(--pencil); font-size: 0.875rem; }
.ledger-card {
  background: #efe8da;
  color: #241f1a;
  max-width: 26rem;
  justify-self: end;
  width: 100%;
  padding: 1.4rem 1.5rem 1.1rem;
  transform: rotate(0.8deg);
  box-shadow: 0 12px 28px rgba(10, 6, 3, 0.55);
  font-size: 0.8125rem;
}
.ledger-card .lc-head {
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: 0.75rem;
  border-bottom: 2px solid #b8341f;
  padding-bottom: 0.4rem;
  margin-bottom: 0.2rem;
}
.ledger-card table { width: 100%; border-collapse: collapse; }
.ledger-card td {
  border-bottom: 1px solid #cfc4b0;
  padding: 0.5rem 0.4rem 0.5rem 0;
  vertical-align: baseline;
}
.ledger-card .lc-no { font-weight: 700; position: relative; width: 3.2rem; }
.ledger-card .lc-kept { text-align: right; color: #6f675c; white-space: nowrap; }
.ledger-card .lc-circle {
  position: absolute;
  left: -9px; top: 0; width: 46px; height: 34px;
  pointer-events: none;
}
.ledger-card .lc-foot { color: #6f675c; padding-top: 0.6rem; font-size: 0.75rem; }

@media (max-width: 900px) {
  .log-grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .ledger-card { justify-self: start; }
}

/* ---------- roll sections ---------- */
/* rolls run at the base beat: half-base each side = 64px roll-to-roll */
.roll { padding: calc(var(--rhythm-base) / 2) 0; border-top: 1px solid var(--rule); }
.roll-head {
  display: flex;
  align-items: baseline;
  gap: 1.25rem;
  flex-wrap: wrap;
  margin-bottom: 0.4rem;
}
.roll-no {
  font-weight: 700;
  font-size: var(--step-1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.roll-title { font-size: var(--step-1); }
.roll-note { color: var(--pencil); font-size: 0.875rem; margin-bottom: 2rem; max-width: 40rem; }

/* the shot: the photograph itself, vignetted toward the middle so the eye
   lands on the frame and not on its corners. text never sits on top of it. */
.shot { display: block; position: relative; max-width: 100%; }
.shot::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 78% 74% at 50% 46%,
      rgba(10, 7, 4, 0) 38%,
      rgba(10, 7, 4, 0.26) 76%,
      rgba(10, 7, 4, 0.52) 100%);
}

/* the first keeper rides full-bleed */
.roll-first { padding-top: 0; }
.viewer.viewer-bleed { display: block; }
.viewer.viewer-bleed .shot { width: 100%; max-width: none; }
.viewer.viewer-bleed img {
  width: 100%;
  max-width: none;
  height: min(74vh, 640px);
  object-fit: cover;
  object-position: center 62%;
}
.viewer.viewer-bleed.viewer-std { display: block; }
.viewer.viewer-bleed.viewer-std .shot { width: auto; max-width: 100%; margin: 0 auto; }
.viewer.viewer-bleed.viewer-std img {
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 74vh;
  object-fit: contain;
  margin: 0 auto;
}
.viewer-bleed figcaption { width: 100%; }
@media (max-width: 560px) {
  .viewer.viewer-bleed img { height: 52vh; }
}

/* the enlarged keeper: caption sits beside a portrait frame like a wall label,
   wraps underneath a landscape frame */
.viewer {
  margin-bottom: 1.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  column-gap: 2rem;
}
.viewer img {
  width: auto;
  max-width: 100%;
  max-height: 78vh;
  height: auto;
}
.viewer figcaption {
  flex: 1 1 18rem;
  display: flex;
  gap: 1rem;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--rule);
  padding: 0.6rem 0;
  font-size: 0.9375rem;
}
.viewer .cap { max-width: 34rem; }
.viewer .frame-no { color: var(--pencil); white-space: nowrap; font-size: 0.8125rem; }

/* the contact strip */
.strip-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.strip {
  display: flex;
  gap: 0;
  background:
    repeating-linear-gradient(90deg, transparent 0 7px, #241f1a 7px 13px, transparent 13px 22px) top / 100% 10px no-repeat,
    repeating-linear-gradient(90deg, transparent 0 7px, #241f1a 7px 13px, transparent 13px 22px) bottom / 100% 10px no-repeat,
    var(--strip);
  padding: 16px 10px;
  width: max-content;
  min-width: 100%;
}
.frame {
  transition: color 0.15s ease;
  background: none;
  border: 0;
  font: inherit;
  color: var(--pencil);
  cursor: pointer;
  padding: 0 8px;
  text-align: left;
  flex: 0 0 auto;
  position: relative;
}
.frame img {
  height: 108px;
  width: auto;
  filter: brightness(0.92);
  transition: filter 0.15s ease;
}
.frame:hover img, .frame[aria-current="true"] img { filter: none; }
.frame .fno {
  display: block;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  padding-top: 4px;
  color: var(--pencil);
}
.frame[aria-current="true"] .fno { color: var(--paper); }
/* the china-marker circle on the keeper */
.frame .circle {
  position: absolute;
  left: -4px;
  top: -8px;
  width: calc(100% + 8px);
  height: calc(100% + 2px);
  pointer-events: none;
  display: none;
}
.frame.keeper .circle { display: block; }
.rebate {
  color: var(--pencil);
  font-size: 0.75rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  align-self: center;
  padding: 0 14px;
  white-space: nowrap;
}
/* with the script dead the strip is a contact sheet you read, not a control:
   the frames are inert, so they are not offered as buttons. */
.strip-hint { color: var(--pencil); font-size: 0.75rem; margin-top: 0.5rem; display: none; }
.strip:not([data-live]) .frame { cursor: default; }

/* ---------- prints ---------- */
/* GRAND pause #2 before the prints — the ask (order a print) gets the air */
.prints {
  padding: calc(var(--rhythm-grand) - var(--rhythm-base) / 2) 0 calc(var(--rhythm-base) / 2);
  border-top: 1px solid var(--rule);
}
.prints h2, .dev h2 {
  font-size: var(--step-2);
  font-weight: 400;
  margin-bottom: 0.5rem;
}
.prints .lede, .dev .lede { color: var(--pencil); max-width: 40rem; margin-bottom: 2.25rem; }
/* density zone: the grid runs a 20px micro-beat, captions tight to frames */
.print-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem 1.25rem;
  margin-bottom: 2.25rem;
}
.print-grid figure { background: none; }
.print-grid .shot { line-height: 0; }
.print-grid img { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; background: var(--strip); }
.print-grid figcaption {
  font-size: 0.8125rem;
  color: var(--pencil);
  padding-top: 0.5rem;
  line-height: 1.5;
}
.print-grid figcaption .fno { color: var(--pencil); display: block; font-size: 0.75rem; letter-spacing: 0.1em; padding-top: 2px; }

.print-terms {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2.5rem;
  max-width: 56rem;
}
.price-table { border-collapse: collapse; width: 100%; font-size: var(--step-0); }
.price-table td {
  border-bottom: 1px solid var(--rule);
  padding: 0.55rem 0;
}
.price-table td:last-child { text-align: right; font-weight: 700; }
.terms-copy p { margin-bottom: 1rem; }
.terms-copy .pencil { color: var(--pencil); font-size: 0.875rem; }

.order-cta {
  display: inline-block;
  margin-top: 1.5rem;
  font-weight: 700;
  font-size: var(--step-1);
  color: var(--paper);
  text-decoration: none;
  position: relative;
  padding-bottom: 8px;
}
.order-cta svg { position: absolute; left: -2px; right: -2px; bottom: 0; width: calc(100% + 4px); height: 9px; }
.order-cta:hover { color: var(--marker-text); }

/* ---------- film dev thursdays ---------- */
/* dev sits at base after prints; bottom compresses pre-footer (0.8x base) */
.dev { padding: calc(var(--rhythm-base) / 2) 0 1.5rem; border-top: 1px solid var(--rule); }
.dev-cols {
  display: grid;
  grid-template-columns: minmax(15rem, 22rem) 1fr;
  gap: 3rem;
  align-items: start;
}
.board {
  background: #efe8da;
  color: #241f1a;
  padding: 2rem 1.5rem 2.25rem;
  transform: rotate(-1.1deg);
  box-shadow: 0 10px 24px rgba(10, 6, 3, 0.55);
}
.board .board-big {
  color: #b8341f;
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1.2;
  letter-spacing: 0.04em;
  transform: rotate(0.7deg);
}
.board .board-small {
  margin-top: 0.9rem;
  font-size: 0.9375rem;
  line-height: 1.5;
}
.board .board-small strong { color: #b8341f; }
.dev-facts p { margin-bottom: 1rem; max-width: 36rem; }
.dev-facts .pencil { color: var(--pencil); font-size: 0.875rem; }

/* ---------- footer ---------- */
.site-foot { border-top: 1px solid var(--rule); padding: 1.75rem 0 3rem; }
.foot-main {
  display: flex;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
  margin-bottom: 2.5rem;
}
.foot-main .stamp { align-self: flex-start; }
.foot-contact { font-size: var(--step-0); line-height: 2; text-align: right; }
.foot-contact .voicemail { color: var(--pencil); font-size: 0.875rem; max-width: 30rem; text-align: right; }
.foot-fine {
  color: var(--pencil);
  font-size: 0.75rem;
  line-height: 1.7;
  max-width: 52rem;
}

/* ---------- responsive ---------- */
@media (max-width: 900px) {
  .print-grid { grid-template-columns: 1fr 1fr; }
  .dev-cols { grid-template-columns: 1fr; }
  .board { max-width: 24rem; }
  .print-terms { grid-template-columns: 1fr; gap: 1.75rem; }
}
@media (max-width: 560px) {
  .open { padding: 1.5rem 0 1.25rem; }
  .print-grid { grid-template-columns: 1fr; }
  .foot-contact, .foot-contact .voicemail { text-align: left; }
  .strip-hint { display: block; }
  .frame img { height: 88px; }
}
