/*
  Portfolio design system — shared by the public vellum page (body.vellum)
  and the gated cyanotype deep-dive pages (body.cyanotype).

  Font trio (approved 2026-08-02: Overpass / Source Serif 4 / Martian Mono):
    display  — Overpass
    body     — Source Serif 4
    utility  — Martian Mono

  This stylesheet does NOT load the fonts itself (no @import — that's
  render-blocking/serial). Any page that includes this stylesheet must
  load Overpass, Source Serif 4, and Martian Mono itself via
  <link rel="preconnect" ...> + <link rel="stylesheet" ...> tags in its
  own <head>, discoverable in parallel with this file. (Task 5's <head>
  requirements are the right place for those <link> tags.)

  No pill/chip/badge components anywhere in this file — tags render as a
  flat mono label list (.tag-list), never as capsule/pill shapes.

  Page-shell / grid containers (.shell, .grid) intentionally target a wide
  max-width (~1500px) with real side padding — the 75ch prose cap applies
  only to paragraph blocks inside a sheet (.prose), never to page layout.
*/

/* ---------------------------------------------------------------------- */
/* Tokens                                                                  */
/* ---------------------------------------------------------------------- */

:root {
  /* vellum */
  --paper: oklch(95.5% 0.015 92);
  --paper-shade: oklch(92% 0.02 90);
  --ink: oklch(30% 0.055 255);
  --ink-soft: oklch(46% 0.045 255);
  --hairline: oklch(30% 0.055 255 / 0.28);
  /* cyanotype */
  --prussian: oklch(25% 0.06 255);
  --prussian-deep: oklch(20% 0.05 255);
  --linework: oklch(88% 0.018 250);
  --linework-soft: oklch(76% 0.028 250);
  /* shared */
  --brass: oklch(60% 0.105 80);
  --space-xs: 4px; --space-sm: 8px; --space-md: 16px;
  --space-lg: 24px; --space-xl: 48px; --space-2xl: 96px;

  /* cyanotype needs a border color the same way vellum has --hairline;
     derived the same way (base hue/chroma/lightness + alpha), not a new hue */
  --hairline-cyanotype: oklch(88% 0.018 250 / 0.28);

  /* type families */
  --font-display: "Overpass", sans-serif;
  --font-body: "Source Serif 4", serif;
  --font-mono: "Martian Mono", monospace;

  /* type scale — 1.333 (Perfect Fourth) ratio off a 1rem base */
  --text-sm: 0.75rem;
  --text-base: 1rem;
  --text-md: 1.333rem;
  --text-lg: 1.777rem;
  --text-xl: 2.369rem;
  --text-2xl: 3.158rem;
  --text-3xl: 4.21rem;

  /* fluid display sizes, clamped between the scale's mobile and desktop steps */
  --text-display-sm: clamp(1.777rem, 1.3rem + 2vw, 2.369rem);
  --text-display-md: clamp(2.369rem, 1.6rem + 3vw, 3.158rem);
  --text-display-lg: clamp(2.75rem, 1.8rem + 4.5vw, 4.21rem);

  --line-height-tight: 1.15;
  --line-height-body: 1.55;

  --page-max: 1500px;
  --page-pad: clamp(1.5rem, 4vw, 4rem);
}

/* ---------------------------------------------------------------------- */
/* Themes                                                                  */
/* ---------------------------------------------------------------------- */

body.vellum {
  --surface: var(--paper);
  --surface-shade: var(--paper-shade);
  --fg: var(--ink);
  --fg-soft: var(--ink-soft);
  --border: var(--hairline);
  background: var(--surface);
  color: var(--fg);
}

body.cyanotype {
  --surface: var(--prussian);
  --surface-shade: var(--prussian-deep);
  --fg: var(--linework);
  --fg-soft: var(--linework-soft);
  --border: var(--hairline-cyanotype);
  /* Light-on-dark body copy needs more leading than dark-on-light to stay
     as readable; bumped ~0.07 over the shared --line-height-body value. */
  --line-height-body: 1.62;
  background: var(--surface);
  color: var(--fg);
}

/* ---------------------------------------------------------------------- */
/* Reset + base                                                            */
/* ---------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--line-height-body);
  min-height: 100vh;
}
h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.3;
  margin: 0;
}
/* Single-line display headlines (the hero name) keep intentional tight
   leading; multi-line headings (card titles, section headings) need the
   >=1.3 legibility floor above instead. */
h1 {
  line-height: var(--line-height-tight);
}
a { color: inherit; }
img, svg { max-width: 100%; display: block; }

code, kbd, .mono {
  font-family: var(--font-mono);
}

/* ---------------------------------------------------------------------- */
/* Accessibility                                                           */
/* ---------------------------------------------------------------------- */

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

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------------- */
/* Page shell — uses available viewport width. The 75ch cap below (.prose) */
/* applies only inside a sheet, never here.                               */
/* ---------------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--page-pad);
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: var(--space-xl);
}

.prose {
  max-width: 75ch;
}

/* ---------------------------------------------------------------------- */
/* .sheet / .sheet-corners                                                 */
/* ---------------------------------------------------------------------- */

.sheet {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  background: var(--surface-shade);
  border: 1px solid var(--border);
  padding: var(--space-lg);
}

/* Four corner tick marks, drawn from exactly two pseudo-elements
   (::before = top-left + top-right, ::after = bottom-left + bottom-right)
   using layered background-image lines only — no side-stripe accent
   borders anywhere in this component. */
.sheet-corners::before,
.sheet-corners::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-repeat: no-repeat;
}
.sheet-corners::before {
  background-image:
    linear-gradient(to right, var(--brass) 1px, transparent 1px),
    linear-gradient(to bottom, var(--brass) 1px, transparent 1px),
    linear-gradient(to left, var(--brass) 1px, transparent 1px),
    linear-gradient(to bottom, var(--brass) 1px, transparent 1px);
  background-size: 14px 1px, 1px 14px, 14px 1px, 1px 14px;
  background-position: top left, top left, top right, top right;
}
.sheet-corners::after {
  background-image:
    linear-gradient(to right, var(--brass) 1px, transparent 1px),
    linear-gradient(to top, var(--brass) 1px, transparent 1px),
    linear-gradient(to left, var(--brass) 1px, transparent 1px),
    linear-gradient(to top, var(--brass) 1px, transparent 1px);
  background-size: 14px 1px, 1px 14px, 14px 1px, 1px 14px;
  background-position: bottom left, bottom left, bottom right, bottom right;
}

/* ---------------------------------------------------------------------- */
/* .title-block — sheet no. / date / rev, bottom-right, mono               */
/* ---------------------------------------------------------------------- */

.title-block {
  align-self: flex-end;
  margin-top: auto;
  display: grid;
  grid-auto-flow: column;
  gap: var(--space-lg);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--fg-soft);
}
.title-block dt {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 11px;
  margin: 0 0 var(--space-xs);
}
.title-block dd {
  margin: 0;
  color: var(--fg);
}

/* ---------------------------------------------------------------------- */
/* .tag-list — flat mono small-caps labels, no pill/chip/badge shapes      */
/* ---------------------------------------------------------------------- */

.tag-list {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-mono);
  font-variant: small-caps;
  font-size: var(--text-sm);
  letter-spacing: 0.03em;
  color: var(--fg-soft);
}
.tag-list li {
  background: none;
  border-radius: 0;
  padding: 0;
}
.tag-list li + li::before {
  content: "\00B7"; /* middot divider */
  margin-inline: var(--space-sm);
  color: var(--brass);
}

/* ---------------------------------------------------------------------- */
/* .dim-callout — metric with dimension-line extensions and end ticks      */
/* ---------------------------------------------------------------------- */

.dim-callout {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}
.dim-callout::before,
.dim-callout::after {
  content: "";
  flex: 1 1 var(--space-lg);
  align-self: center;
  height: var(--space-sm);
  border-top: 1px solid var(--brass);
  background-image: linear-gradient(var(--brass), var(--brass));
  background-repeat: no-repeat;
  background-size: 1px var(--space-sm);
}
.dim-callout::before { background-position: left center; }
.dim-callout::after { background-position: right center; }

.dim-value {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  text-align: center;
}
.dim-figure {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--text-display-sm);
  line-height: 1;
  color: var(--fg);
  white-space: nowrap;
}
.dim-label {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-variant-caps: small-caps;
  letter-spacing: 0.02em;
  color: var(--fg-soft);
}

/* ---------------------------------------------------------------------- */
/* .gate-header — small brand link atop the gated cyanotype pages         */
/* ---------------------------------------------------------------------- */

.gate-header {
  padding-block: var(--space-lg);
}
.gate-header-brand {
  text-decoration: none;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
}

/* ---------------------------------------------------------------------- */
/* #gate / .gate-frame — composed, centered lock-screen card               */
/* ---------------------------------------------------------------------- */

#gate {
  display: flex;
  justify-content: center;
  min-height: 60vh;
  padding-block: clamp(2rem, 10vh, 6rem) var(--space-2xl);
}

/* .gate-compose pairs the lock card with a Sheet/Status/Access title-block,
   the same cover-sheet composition move as the public page's .hero-meta:
   it fills the wide cyanotype void beside the card with real drafting-sheet
   content instead of leaving it blank. Hidden below 960px rather than
   stacking under the card, matching the hero-meta breakpoint. */
.gate-compose {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xl);
}

.gate-frame {
  width: 100%;
  max-width: 30rem;
  padding: var(--space-2xl) var(--space-xl);
  align-self: center;
}

.gate-frame-kicker {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--brass);
}

.gate-frame-teaser {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--fg-soft);
}

.gate-meta {
  display: none;
  flex-shrink: 0;
  gap: var(--space-lg);
}
.gate-meta-rule {
  position: relative;
  width: 1px;
  align-self: stretch;
  background-image: linear-gradient(var(--brass), var(--brass));
  background-repeat: no-repeat;
  background-size: 1px 100%;
  opacity: 0.6;
}
.gate-meta-rule::before,
.gate-meta-rule::after {
  content: "";
  position: absolute;
  left: -5px;
  width: 11px;
  height: 1px;
  background: var(--brass);
}
.gate-meta-rule::before { top: 0; }
.gate-meta-rule::after { bottom: 0; }
.gate-meta-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  margin: 0;
  font-family: var(--font-mono);
  white-space: nowrap;
}
.gate-meta-block div + div {
  padding-top: var(--space-md);
  border-top: 1px solid var(--border);
}
.gate-meta-block dt {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 11px;
  color: var(--fg-soft);
  margin: 0 0 var(--space-xs);
}
.gate-meta-block dd {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--fg);
}
@media (min-width: 960px) {
  .gate-meta {
    display: flex;
  }
}

/* ---------------------------------------------------------------------- */
/* .gate-form — password gate on cyanotype pages                          */
/* ---------------------------------------------------------------------- */

.gate-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  max-width: 40ch;
}
.gate-form label {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fg-soft);
}
.gate-form input[type="password"] {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--border);
  padding: var(--space-sm) var(--space-md);
}
.gate-form button {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--brass);
  color: var(--prussian-deep);
  border: none;
  padding: var(--space-sm) var(--space-lg);
  cursor: pointer;
  align-self: flex-start;
}
.gate-form button:disabled {
  cursor: progress;
  opacity: 0.65;
}
.gate-form .gate-error {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--fg);
  border-top: 1px solid var(--border);
  padding-top: var(--space-sm);
}

/* ---------------------------------------------------------------------- */
/* #sheet-content — decrypted case-study body, injected via gate.js.       */
/* Scoped selectors (not a container-wide max-width) so page-shell/grid    */
/* rules elsewhere are untouched, per the 75ch-only-on-paragraphs rule.    */
/* ---------------------------------------------------------------------- */

#sheet-content p,
#sheet-content li,
#sheet-content dd {
  max-width: 75ch;
}

/* ---------------------------------------------------------------------- */
/* .decision-log / .decision-item — Decision/Alternatives/Why triads       */
/* ---------------------------------------------------------------------- */

.decision-log {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
  margin: var(--space-lg) 0 0;
  padding: 0;
  counter-reset: decision;
}

.decision-item {
  position: relative;
  display: grid;
  grid-template-columns: minmax(7rem, 9.5rem) minmax(0, 75ch);
  column-gap: var(--space-lg);
  row-gap: var(--space-sm);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--border);
  counter-increment: decision;
}

.decision-item::before {
  content: counter(decision, decimal-leading-zero);
  position: absolute;
  top: calc(-0.5 * var(--text-sm) - 1px);
  left: 0;
  background: var(--surface-shade);
  padding-inline-end: var(--space-sm);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: 0.06em;
  color: var(--brass);
}

.decision-item dt {
  margin: 0;
  padding-top: 0.2em;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--brass);
}

.decision-item dd {
  margin: 0;
  color: var(--fg);
}

@media (max-width: 640px) {
  .decision-item {
    grid-template-columns: 1fr;
    row-gap: var(--space-xs);
  }
  .decision-item dd {
    margin-bottom: var(--space-sm);
  }
}
