/* Website v6 — single stylesheet, top-bar navigation only, artboard model. */

* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --bg:      #262421;    /* warm near-black */
  --surface: #2e2b28;    /* slight elevation */
  --text:    #d8d5cf;    /* warm off-white */
  --muted:   #948f88;    /* secondary text */
  --accent:  #b85c45;    /* terracotta — hovers, active states */
  --line:    rgba(216,213,207,.14);  /* subtle borders */
}

html {
  -webkit-text-size-adjust: 100%;
  -moz-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

html, body {
  background: var(--bg);
  color: var(--text);
}

body {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
  text-decoration: none;
}

img, video {
  max-width: 100%;
  display: block;
}

::selection {
  background: var(--text);
  color: var(--bg);
}

.artboard-text mark, .writing-article mark { background: var(--text); color: var(--bg); padding: 0 0.12em; -webkit-box-decoration-break: clone; box-decoration-break: clone; }

/* ── top bar ─────────────────────────────────────────────────────────────── */

.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 1.5rem;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  z-index: 200;
  transition: transform 0.3s ease;
}

.topbar-hidden {
  transform: translateY(-100%);
}

.topbar-name {
  font-size: 1.1rem;
  font-weight: 500;
  color: var(--text);
}

.topbar-nav {
  display: flex;
  gap: 1.5rem;
}

.topbar-nav a {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  transition: color 0.15s ease;
}

.topbar-nav a:hover,
.topbar-nav a.active {
  color: var(--accent);
}

/* fullscreen toggle button — lives at the end of .topbar-nav */
.fs-btn {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0.5rem;
  transition: color 0.15s ease;
}

.fs-btn:hover { color: var(--text); }

/* fullscreen active: hide chrome but keep the toggle reachable as the exit */
.topbar.fs-active {
  background: transparent;
  border-bottom-color: transparent;
  pointer-events: none;
}

.topbar.fs-active .topbar-name,
.topbar.fs-active .topbar-nav a {
  visibility: hidden;
}

.topbar.fs-active .fs-btn {
  pointer-events: auto;
}

/* ── artboard ────────────────────────────────────────────────────────────── */

.artboard-wrap {
  overflow: hidden;
  width: 100%;
  padding-top: 56px;
}

.artboard {
  position: relative;
  width: 1440px;
  overflow: hidden;
}

.artboard-el {
  position: absolute;
}

.artboard-el img {
  display: block;
  width: 100%;
  height: auto;
  cursor: zoom-in;
}

.artboard-el[data-lightbox]:hover img {
  opacity: 0.92;
  transition: opacity 0.15s;
}

.artboard-el video {
  display: block;
  width: 100%;
  height: auto;
}

/* ── artboard frames (Card I) ─────────────────────────────────────────────── */
/* Opt-in per-element hairline border. Text also gets 14px padding (boxed
   text); images get border-only (printed-plate look). The `framed` class
   is emitted by build.js only when el.frame === true AND the site-wide
   kill switch (site.frames) is not false — so absent or frames:false
   produces byte-identical output. Inert unless .framed is present. */
.artboard-el.framed {
  border: 1px solid var(--line);
}

.artboard-text.framed {
  padding: 14px;
}

/* Per-layout page frame: faint inset hairline rule around the whole
   artboard. Rendered as a pseudo-element so it is never serialized into
   element data — it's a class on the .artboard div driven by
   data.pageFrame. Inert unless .page-frame is present. */
.artboard.page-frame::after {
  content: '';
  position: absolute;
  inset: 20px;
  border: 1px solid var(--line);
  pointer-events: none;
}

/* ── artboard fit rows (Card H1) ─────────────────────────────────────────── */
/* AUTO-FIT: full-width image rows get capped to one screen by --fitmax, set
   on the .artboard element by the viewport scaler in build.js. The element
   box keeps its artboard footprint (left/top/width) and top edge; the image
   shrink-wraps to fit --fitmax and centers horizontally inside the box.
   Side matting (gaps) is acceptable; cropping is not. */
.artboard-el.fit {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  max-height: var(--fitmax, 100000px);
}

.artboard-el.fit img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: var(--fitmax, 100000px);
  object-fit: contain;
}

/* ── artboard fill modes (Card J) ─────────────────────────────────────────── */
/* Opt-in per-element fullscreen fit. Only emitted by build.js when
   el.fit === 'fill' (absent / 'free' = byte-identical legacy). The
   auto-fit `fit` class (Card H1) is suppressed for any element with an
   explicit `fit`, so the two never coexist on one element. Aspect
   decides the variant:
     landscape (aspect ≥ 1.5) → fill-cover: edge-to-edge, thin sliver
       crop top/bottom on landscape screens via object-fit: cover.
     portrait/square/4:3 → fill-height: height clamped, width auto,
       centered horizontally in the element box — NEVER crops.
   Both clamp height to min(var(--fitmax), 788px). --fitmax is set on
   .artboard by the viewport scaler in build.js and reflects the
   available vertical space at the current scale; 788 is the per-element
   fullscreen cap (matches the baked artboard reservation in
   elementBottom so the live clamp and the baked flow never disagree). */
.artboard-el.fill-cover img {
  width: 100%;
  height: min(var(--fitmax, 100000px), 788px);
  object-fit: cover;
  display: block;
}

.artboard-el.fill-height {
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

.artboard-el.fill-height img {
  width: auto;
  height: min(var(--fitmax, 100000px), 788px);
  max-width: 100%;
  object-fit: contain;
  display: block;
}

/* Below 640px viewport width, fill elements render at natural height
   (mobile stays in normal flow — no fullscreen snapping). The wrapper's
   inline width:% is preserved; the image just fills that width at its
   natural aspect. */
@media (max-width: 640px) {
  .artboard-el.fill-cover img,
  .artboard-el.fill-height img {
    width: 100%;
    height: auto;
    max-width: none;
    object-fit: contain;
  }

  .artboard-el.fill-height {
    display: block;
  }
}

/* ── artboard text ───────────────────────────────────────────────────────── */

.artboard-text {
  color: var(--text);
  white-space: pre-wrap;
}

.artboard-text-headline {
  font-size: 3rem;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
}

.artboard-text-headline strong {
  font-weight: 700;
}

.artboard-text-title {
  font-size: 1.5rem;
  font-weight: 500;
  line-height: 1.25;
}

.artboard-text-body {
  font-size: 0.9rem;
  line-height: 1.6;
}

.artboard-text-meta {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-family: "Courier New", Courier, monospace;
  color: var(--muted);
}

/* ── Card W: text boxes as links ────────────────────────────────────────── */
.artboard-link {
  color: inherit;
  text-decoration: none;
  display: block;
}

.artboard-link:hover {
  color: var(--accent);
}

/* ── Q1: Typography toggles ────────────────────────────────────────────── */
.caps { text-transform: uppercase; }
.tracking-wide { letter-spacing: 0.12em; }
.leading-loose { line-height: 1.8; }
.leading-tight { line-height: 1.25; }
.accent { color: var(--accent); }
.dropcap::first-letter {
  font-size: 3.2em;
  float: left;
  line-height: 0.9;
  padding-right: 0.08em;
}

/* ── Q4: rule divider element ──────────────────────────────────────────── */
.artboard-rule {
  border-top: 1px solid var(--line);
}

/* ── Card L: mobile linearization (phone feed) ──────────────────────────── */
/* Phones ≤700px: the viewport scaler shrinks the 1440px artboard to ~27%,
   making text unreadable. Instead, the page becomes a DERIVED vertical
   scroll feed: every artboard element keeps its DOM + composed order, but
   the .artboard switches to a row-wrap flex flow with all elements at
   100% basis (visually a column, but enables 50/50 pairing in Card M via
   pure data — no rework needed here). Visual y-order is rebuilt with
   `order: var(--rank, 0)` emitted by build.js (Card L). Desktop is
   byte-identical: every override is !important and gated by this media
   query; --rank is inert outside it. iPad (768px+) keeps the scaled
   artboard. /photographs/ grid is not an artboard — untouched. */
@media (max-width: 700px) {
  .artboard-wrap {
    height: auto !important;
    padding-top: 56px;
  }

  /* position stays `relative` so Card I .page-frame::after keeps anchoring. */
  .artboard {
    width: 100% !important;
    height: auto !important;
    transform: none !important;
    display: flex;
    flex-flow: row wrap;
    align-content: flex-start;
  }

  .artboard-el,
  .artboard-link {
    position: static !important;
    left: auto !important;
    top: auto !important;
    margin: 0 0 22px;
    width: var(--m-w, 100%) !important;
    flex-basis: var(--m-w, 100%) !important;
    order: var(--m-order, var(--rank, 0));
  }

  .artboard-el img {
    width: 100% !important;
    height: auto !important;
    max-height: none !important;
    object-fit: contain !important;
    display: block;
  }

  .artboard-el video {
    width: 100% !important;
    height: auto !important;
    display: block;
  }

  /* Neutralize Card H1 auto-fit clamp inside the feed band. */
  .artboard-el.fit {
    display: block;
    max-height: none;
  }

  /* Neutralize Card J fill-cover / fill-height clamps inside the feed
     band. (Card J already reverts <640px at line 244; this covers the
     whole ≤700px band so the phone feed never crops.) */
  .artboard-el.fill-cover img {
    width: 100% !important;
    height: auto !important;
    object-fit: contain !important;
  }

  .artboard-el.fill-height {
    display: block;
  }

  .artboard-el.fill-height img {
    width: 100% !important;
    height: auto !important;
    max-width: none;
    object-fit: contain !important;
  }

  /* Card H inline fixed height must NOT reserve in the feed (fixed h +
     overflow:visible would overlap the next flex item). */
  .artboard-text {
    padding: 0 20px;
    box-sizing: border-box;
    height: auto !important;
  }

  /* Readable mobile defaults — NO !important so authored inline font-size
     (Card B) still wins. Headline/title are already large. */
  .artboard-text-body {
    font-size: 16px;
    line-height: 1.65;
  }

  .artboard-text-meta {
    font-size: 0.75rem;
  }

  /* Q4: rule in feed — full-width hairline with normal element margins */
  .artboard-rule {
    border-top: 1px solid var(--line);
  }
}

/* ── direction capabilities line ────────────────────────────────────────── */

.capabilities-line {
  font-family: "Courier New", Courier, monospace;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  padding: 3rem 1.5rem;
  text-align: center;
}

/* ── photographs grid ───────────────────────────────────────────────────── */

/* Edge-to-edge: topbar above (padding-top clears the fixed bar), footer
   below, no horizontal padding/margin. Card C zeroes padding-top in
   fullscreen via inline style on this element. */
.photographs-page {
  padding: 56px 0 0;
}

/* grid-template-columns is set inline by build.js (baked first-paint default
   from a 1440x900 reference viewport) and refined on load + resize by the
   photographs-page sizer script. With JS disabled the baked inline value
   remains; if it is stripped, the grid degrades to a single column. */
.photo-grid {
  display: grid;
  gap: 3px;
}

.photo-cell {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--surface);
}

.photo-cell img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform 0.3s ease;
}

.photo-cell:hover img {
  transform: scale(1.03);
}

.photo-sheet-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 10px 10px 8px;
  border-bottom: 1px solid var(--border);
  font-family: 'Courier New', monospace;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}

.photo-sheet-header .psh-right {
  text-align: right;
}

.photo-cell .photo-num {
  position: absolute;
  top: 5px;
  left: 7px;
  z-index: 2;
  pointer-events: none;
  font-family: 'Courier New', monospace;
  font-size: 9px;
  letter-spacing: .08em;
  color: var(--muted);
  text-shadow: 0 0 3px var(--bg), 0 0 3px var(--bg);
}

.photo-cell .photo-num.select {
  color: var(--accent);
}

/* ── lightbox ────────────────────────────────────────────────────────────── */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(14, 14, 13, 0.72);
  backdrop-filter: blur(14px) saturate(0.85);
  -webkit-backdrop-filter: blur(14px) saturate(0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease;
}

.lightbox.open {
  opacity: 1;
  visibility: visible;
}

.lb-content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.lightbox img {
  max-width: 78vw;
  max-height: 84vh;
  object-fit: contain;
}

.lb-info {
  margin-top: 0.6rem;
  max-width: 300px;
}

.lb-info-title {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid rgba(232,230,226,0.25);
  padding-bottom: 1px;
  transition: border-color 0.15s;
  font-family: inherit;
}

.lb-info-title:hover { border-color: var(--accent); }

.lb-info-intro {
  margin: 0.45rem 0 0;
  font-size: 0.68rem;
  line-height: 1.55;
  color: var(--muted);
  max-width: 34ch;
}

@media (max-width: 700px) {
  .lb-info-intro { display: none; }
}

.lb-close {
  position: absolute;
  top: 1.5rem;
  right: 1.5rem;
  background: none;
  border: none;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--text);
  cursor: pointer;
}

.lb-counter {
  position: absolute;
  bottom: 1.5rem;
  left: 1.5rem;
  font-family: "Courier New", Courier, monospace;
  font-size: 0.75rem;
  color: var(--text);
}

.lb-arrows {
  position: absolute;
  bottom: 1.5rem;
  right: 1.5rem;
  display: flex;
  gap: 1rem;
}

.lb-arrow {
  background: none;
  border: none;
  font-size: 1.75rem;
  color: var(--text);
  cursor: pointer;
  padding: 0.5rem;
}

/* ── series page ─────────────────────────────────────────────────────────── */

.series-page {
  padding-top: 56px;
  max-width: 900px;
  margin: 0 auto;
}

.series-header {
  padding: 3rem 1.5rem 2rem;
}

.series-title {
  font-size: 2rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.series-meta {
  margin-top: 0.5rem;
  font-family: "Courier New", Courier, monospace;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
}

.series-prose {
  margin-top: 1.5rem;
  font-size: 0.9rem;
  line-height: 1.6;
  max-width: 60ch;
}

.series-images {
  display: flex;
  flex-direction: column;
  gap: 2rem;
  padding: 0 1.5rem;
}

.series-image img {
  width: 100%;
  height: auto;
  cursor: pointer;
}

.series-nav {
  display: flex;
  justify-content: space-between;
  padding: 3rem 1.5rem;
  border-top: 1px solid var(--line);
  margin-top: 3rem;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.series-nav a {
  color: var(--muted);
  transition: color 0.15s ease;
}

.series-nav a:hover {
  color: var(--accent);
}

/* ── series page (artboard variant) ──────────────────────────────────────── */

.series-page-artboard {
  padding-top: 0;
  max-width: none;
  margin: 0;
}

.series-page-artboard .artboard {
  max-width: none;
}

.series-page-artboard .series-nav {
  max-width: 900px;
  margin: 0 auto;
}

/* ── about page ──────────────────────────────────────────────────────────── */

.about-page {
  padding-top: 56px;
  max-width: 50ch;
  margin: 0 auto;
  min-height: calc(100vh - 56px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.25rem;
  padding-left: 1.5rem;
  padding-right: 1.5rem;
  padding-bottom: 4rem;
}

.about-line {
  font-size: 1.1rem;
  line-height: 1.6;
}

.about-availability {
  margin-top: 1rem;
  font-size: 0.9rem;
  color: var(--muted);
}

.about-capabilities {
  font-family: "Courier New", Courier, monospace;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
}

.about-city {
  font-family: "Courier New", Courier, monospace;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
}

.about-email a {
  color: var(--accent);
  font-size: 0.95rem;
}

/* ── writing index (conditional) ────────────────────────────────────────── */

.writing-index {
  padding-top: 56px;
  max-width: 700px;
  margin: 0 auto;
  padding-bottom: 4rem;
}

.writing-row {
  display: flex;
  justify-content: space-between;
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--line);
}

.writing-year {
  color: var(--muted);
  font-family: "Courier New", Courier, monospace;
  font-size: 0.8rem;
}

/* ── writing articles (conditional) ─────────────────────────────────────────── */

.writing-article {
  padding-top: 56px;
  max-width: 660px;
  margin: 0 auto;
  font-size: 17px;
  line-height: 1.7;
}

@media (max-width: 700px) {
  .writing-article {
    padding-top: 96px;
  }
}

.writing-article p {
  margin: 1.5rem 0;
}

.writing-article blockquote.wa-pull {
  margin: 2rem 0;
  padding: 1.5rem 0 1.5rem 1.5rem;
  border-left: 2px solid var(--accent);
  font-size: 1.1rem;
  font-style: italic;
}

.writing-article .wa-rule {
  margin: 2rem auto;
  border: 0;
  border-top: 1px solid var(--line);
  width: 33%;
}

.writing-article .wa-full {
  width: min(960px, 92vw);
  margin-left: calc((100% - min(960px, 92vw)) / 2);
  margin-right: 0;
  margin-top: 2rem;
  margin-bottom: 2rem;
  text-align: center;
}

.writing-article .wa-full img {
  width: 100%;
  height: auto;
}

.writing-article .wa-half {
  width: 60%;
  margin: 2rem auto;
  text-align: center;
}

.writing-article .wa-half img {
  width: 100%;
  height: auto;
}

.writing-article .wa-pair {
  display: flex;
  gap: 16px;
  margin: 2rem auto;
  width: min(960px, 92vw);
}

.writing-article .wa-pair .wa-full {
  width: 48%;
  margin: 0;
}

.writing-article .wa-pair .wa-full:first-child img {
  transform: rotate(-1.2deg);
}

.writing-article .wa-pair .wa-full:last-child img {
  transform: rotate(1.2deg);
}

.writing-article figure figcaption {
  margin-top: 0.5rem;
  font-family: "Courier New", Courier, monospace;
  font-size: 0.8rem;
  color: var(--muted);
}

@media (max-width: 700px) {
  .writing-article .wa-pair {
    flex-direction: column;
    gap: 0;
    width: 100%;
  }
  
  .writing-article .wa-pair .wa-full {
    width: 100%;
    margin: 1rem 0;
  }
  
  .writing-article .wa-pair .wa-full img {
    transform: none !important;
  }
}

/* ── footer ──────────────────────────────────────────────────────────────── */

.site-footer {
  padding: 3rem 1.5rem 4rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  text-align: center;
  border-top: 1px solid var(--line);
}

.site-footer a {
  color: var(--accent);
  font-size: 0.95rem;
}

.footer-meta {
  font-family: "Courier New", Courier, monospace;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}

/* ── mobile ──────────────────────────────────────────────────────────────── */

@media (max-width: 640px) {
  .topbar {
    height: auto;
    min-height: 96px;
    flex-direction: column;
    justify-content: center;
    padding: 0.75rem 1rem;
    gap: 0.5rem;
  }

  .topbar-name {
    text-align: center;
  }

  .topbar-nav {
    justify-content: center;
    flex-wrap: wrap;
    gap: 1rem;
  }

  .photographs-page {
    padding-top: 96px;
  }

  .photo-grid {
    /* !important so the mobile 3-col rule wins over the inline baked default
       and the runtime sizer's inline style. SPEC §1: grid goes 3-col under
       640px. Desktop auto-sizing is handled by the sizer script. */
    grid-template-columns: repeat(3, 1fr) !important;
  }

  .series-page,
  .about-page,
  .writing-index {
    padding-top: 96px;
  }

  .series-nav {
    flex-direction: column;
    gap: 0.75rem;
  }

  .artboard-wrap {
    padding-top: 96px;
  }

  .capabilities-line {
    padding: 2rem 1rem;
  }
}

/* ── reduced motion ──────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    animation: none !important;
  }
}
