/* ============================================================
   johlem.com — portrait
   Three grounds, one layout. The visitor can switch the paper;
   the photographs never move.

   Ground values were chosen by measuring the actual portraits:
   bone leaves every frame with at least 40 points of luminance
   separation from the page. Charcoal and blush leave two of six
   frames under 30, so those two grounds carry a hairline edge
   that is doing real work, not decoration.
   ============================================================ */

:root {
  /* --- BONE (default) ---------------------------------------- */
  --ground:     #EDE8E0;  /* the paper */
  --ground-2:   #DDD5CA;  /* rules on the paper */
  --ink:        #12100E;  /* all type */
  --ink-quiet:  #12100E85;/* small type */
  --accent:     #B0776F;  /* your pink, deepened to hold against bone */
  --soft:       #F1C8CB;  /* your original pink, for soft fills */
  --edge:       #12100E2e;/* hairline around each photograph */
  --grain:      0.07;

  /* --- type -------------------------------------------------- */
  /* System faces only: nothing is downloaded, nothing is tracked. */
  --font-display: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-utility: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
                  "Liberation Mono", monospace;

  /* --- rhythm ------------------------------------------------ */
  --gutter: clamp(20px, 4vw, 56px);
  --hair:   1px;

  /* Your portraits are all 2:3. Frames are sized by height, so
     nothing is ever cropped and every frame lands identically. */
  --frame-height: min(62vh, 660px);
}

/* --- CHARCOAL ------------------------------------------------ */
[data-theme="dark"] {
  --ground:    #141312;
  --ground-2:  #EDEBE826;
  --ink:       #EDEBE8;
  --ink-quiet: #EDEBE880;
  --accent:    #C9A29C;
  --soft:      #C9A29C;
  --edge:      #EDEBE833;
  --grain:     0.05;
}

/* --- BLUSH --------------------------------------------------- */
[data-theme="blush"] {
  --ground:    #F1C8CB;
  --ground-2:  #D3959B;
  --ink:       #0A0A0A;
  --ink-quiet: #0A0A0A99;
  --accent:    #8C4A44;
  --soft:      #FFFFFF;
  --edge:      #0A0A0A2e;
  --grain:     0.08;
}

/* If the visitor has never chosen, follow the operating system. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --ground:    #141312;
    --ground-2:  #EDEBE826;
    --ink:       #EDEBE8;
    --ink-quiet: #EDEBE880;
    --accent:    #C9A29C;
    --soft:      #C9A29C;
    --edge:      #EDEBE833;
    --grain:     0.05;
  }
}

/* ---- reset (only what we actually need) --------------------- */
*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; padding: 0; height: 100%; }

body {
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-display);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background 340ms ease, color 340ms ease;
}

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

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

/* ---- paper grain -------------------------------------------- */
.grain {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: var(--grain);
  mix-blend-mode: multiply;
  pointer-events: none;
  z-index: 10;
}
[data-theme="dark"] .grain { mix-blend-mode: screen; }

/* ============================================================
   Page frame — masthead / photographs / contact
   ============================================================ */

.sheet {
  min-height: 100%;
  min-height: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  padding: var(--gutter);
  gap: var(--gutter);
}

.masthead { display: flex; }

.logo {
  display: inline-grid;
  grid-template-columns: auto auto auto;
  align-items: center;
  gap: 14px;
}

.logo__word {
  font-size: clamp(21px, 2.9vw, 31px);
  font-weight: 700;
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  line-height: 1;
}

.logo__rule {
  width: clamp(24px, 5vw, 60px);
  height: var(--hair);
  background: var(--ink);
}

.logo__sub {
  font-family: var(--font-utility);
  font-size: 11px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--ink-quiet);
}

/* ============================================================
   The photographs
   ============================================================ */

.stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 3vh, 30px);
}

/* One slot on narrow screens, three across on wide ones.
   Three 2:3 portraits will not fit a phone, so the set
   collapses to a single frame rather than shrinking. */
.set {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(14px, 2.2vw, 30px);
  margin: 0;
}

.slot { animation: settle 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.slot:nth-child(2) { animation-delay: 70ms; }
.slot:nth-child(3) { animation-delay: 140ms; }

.slot__window {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--frame-height);
}

/* Two layers per slot so one frame can dissolve into the next.
   The hairline guarantees an edge even where the photograph and
   the ground are close in value. */
.frame {
  height: var(--frame-height);
  width: auto;
  max-width: 100%;
  object-fit: contain;
  outline: var(--hair) solid var(--edge);
  outline-offset: -1px;
  opacity: 0;
  transition: opacity 620ms ease;
}
.frame--b { position: absolute; inset: 0; margin: auto; }
.frame.is-visible { opacity: 1; }

.slot__cap {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-top: 10px;
  font-family: var(--font-utility);
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.cap__mark  { color: var(--ink-quiet); }
.cap__index { color: var(--accent); font-variant-numeric: tabular-nums; }

/* Empty / error message, shown in place of the photographs */
.notice {
  font-family: var(--font-utility);
  font-size: 12px;
  line-height: 1.7;
  letter-spacing: 0.04em;
  color: var(--ink-quiet);
  text-align: center;
  max-width: 34ch;
  margin: 0;
  padding: 60px 12px;
}
.notice code { color: var(--ink); background: var(--soft); padding: 1px 5px; }

/* ---- next control ------------------------------------------- */
.next {
  appearance: none;
  background: transparent;
  border: var(--hair) solid var(--ink);
  border-radius: 0;
  color: var(--ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 20px;
  font-family: var(--font-utility);
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  transition: background 200ms ease, color 200ms ease;
}
.next:hover { background: var(--ink); color: var(--ground); }
.next[disabled] { opacity: 0.3; cursor: default; }
.next[disabled]:hover { background: transparent; color: var(--ink); }

.next__glyph {
  font-size: 14px;
  line-height: 1;
  transition: transform 500ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
.next:hover .next__glyph { transform: rotate(180deg); }

/* ============================================================
   Contact and the ground switcher
   ============================================================ */

.colophon {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  border-top: var(--hair) solid var(--ground-2);
  padding-top: 16px;
  font-family: var(--font-utility);
  font-size: 12px;
  letter-spacing: 0.14em;
}

.mail {
  padding-bottom: 2px;
  border-bottom: 2px solid var(--soft);
  transition: border-color 200ms ease;
}
.mail:hover { border-bottom-color: var(--accent); }

/* Three small swatches. Deliberately quiet — this is a comfort
   control, not a feature. */
.grounds {
  display: flex;
  align-items: center;
  gap: 8px;
}

.grounds__label {
  font-size: 9px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-quiet);
  margin-right: 4px;
}

.swatch {
  appearance: none;
  width: 15px;
  height: 15px;
  padding: 0;
  border-radius: 0;
  border: var(--hair) solid var(--ink-quiet);
  cursor: pointer;
  transition: transform 160ms ease, border-color 160ms ease;
}
.swatch:hover { transform: translateY(-2px); }
.swatch[aria-pressed="true"] {
  border-color: var(--ink);
  box-shadow: 0 0 0 2px var(--ground), 0 0 0 3px var(--ink);
}

.swatch--bone  { background: #EDE8E0; }
.swatch--dark  { background: #141312; }
.swatch--blush { background: #F1C8CB; }

/* ============================================================
   Motion
   ============================================================ */

@keyframes settle {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

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

/* ============================================================
   Small screens
   ============================================================ */

@media (max-width: 899px) {
  :root { --frame-height: 56vh; }
  .logo { gap: 10px; grid-template-columns: auto auto; }
  .logo__word { letter-spacing: 0.26em; text-indent: 0.26em; }
  .logo__rule { display: none; }
  .colophon { flex-direction: column; align-items: flex-start; gap: 14px; }
}

@media (max-height: 620px) {
  :root { --frame-height: 46vh; }
  .sheet { gap: clamp(12px, 2vh, 20px); }
}
