/* ============================================================
   Hidden Fire Studio — Wendy Kusmaul Keeling
   Palette is drawn from an atmospheric kiln: raw clay, wood ash,
   smoke, and the oxblood flash that only shows up where the fire
   touched. The ember color is used sparingly on purpose.
   ============================================================ */

:root {
  /* Warm all the way through, with steps in it. The old palette was one
     temperature top to bottom, so nothing separated from anything else.
     Now there are four grounds — dark header, light page, warm band,
     dark footer — and the red appears at both weights.               */

  --ink:       #241408;  /* warm dark brown-black — 14.9:1 on canvas */
  --espresso:  #2A1710;  /* header and footer ground */
  --canvas:    #F7E9D3;  /* the page — warm cream, not beige */
  --band:      #EFD9BC;  /* alternating sections, panels, image wells */
  --band-deep: #E5C79F;  /* rules, edges, the deepest warm step */
  --smoke:     #7A5A44;  /* secondary text — 5.2:1 on canvas */
  --cream:     #F7E9D3;  /* type on the dark grounds */

  --red:     #FF020C;    /* the brand red — shapes, rules, fills */
  --red-ink: #C40009;    /* the same red, text-safe — 5.2:1 on canvas */
  --ember:   var(--red-ink);

  /* older names kept pointing at the new ones so nothing breaks */
  --ash:   var(--canvas);
  --ash-2: var(--band-deep);
  --kiln:  var(--espresso);

  --display: "Fraunces", Georgia, serif;
  --body:    "Karla", "Helvetica Neue", Arial, sans-serif;
  --label:   "Space Mono", "Courier New", monospace;

  --measure: 62ch;
  --gut: clamp(1.25rem, 4vw, 3rem);
  --max: 1180px;
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

body {
  margin: 0;
  background: var(--ash);
  position: relative;
  color: var(--ink);
  font-family: var(--body);
  font-size: 1.0625rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

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

/* ---------- ground texture ----------
   Two layers: a fine tooth like laid paper, and a soft warm bloom in
   the upper left the way a kiln flashes one side of a pot. Both sit
   under everything and never intercept a click.                      */

body::before {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
  mix-blend-mode: multiply;
}
body::after {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(120vw 90vh at 8% -10%, rgba(196,124,54,.16), transparent 60%),
    radial-gradient(80vw 70vh at 100% 8%, rgba(126,31,22,.08), transparent 55%),
    radial-gradient(90vw 80vh at 50% 108%, rgba(58,44,30,.11), transparent 60%);
}
.masthead, main, footer { position: relative; z-index: 1; }

a { color: var(--ember); text-decoration: none; border-bottom: 1px solid rgba(126,31,22,.3); }
a:hover { border-bottom-color: var(--ember); }
a:focus-visible, button:focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: 3px;
}

/* ---------- type scale ---------- */

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 400;
  font-variation-settings: "SOFT" 40, "WONK" 1;
  line-height: 1.06;
  margin: 0;
  letter-spacing: -0.015em;
}

h1 { font-size: clamp(2.6rem, 7vw, 5rem); }

/* ---------- banner headings ----------
   Page titles run the full width of the page instead of sitting in a
   narrow column. Size is derived from the character count so a long
   name and a short one both reach the same right edge.               */

.banner {
  display: block;
  width: 100%;
  margin: 0 0 1.5rem;
  line-height: .92;
  letter-spacing: -0.03em;
  text-wrap: balance;
  /* 1.72 is the average glyph-width ratio for Fraunces at this weight;
     dividing the viewport by the character count lands the last letter
     near the right edge without measuring in JS. */
  font-size: min(
    calc((100vw - 2 * var(--gut)) / (var(--chars) * 0.58)),
    calc((var(--max) - 2 * var(--gut)) / (var(--chars) * 0.58))
  );
}
.banner .row { display: block; white-space: nowrap; }

/* Two heading roles, so sizes stay consistent page to page:
   .banner        — the name. Sized to fill the page width. Identical on
                    Work and CV because it's the same 21 characters.
   .banner.fixed  — every other page heading. One shared size regardless
                    of length, so About, Statement, and Contact match
                    each other instead of each landing somewhere else. */

.banner.fixed {
  font-size: clamp(2.1rem, 5.4vw, 3.9rem);
  line-height: 1.02;
}
.banner.fixed .row { white-space: normal; }

/* a quoted heading hangs its opening mark into the left margin so the
   first letter still lines up with everything below it */
.banner.quoted { text-indent: -0.4em; }

/* attribution under a quoted heading — same size and rhythm as the
   eyebrow labels above it, so every small label on the site matches */
.attrib {
  font-family: var(--label);
  font-size: .7rem; letter-spacing: .22em; text-transform: uppercase;
  color: var(--smoke);
  margin: .9rem 0 0;
}
.banner em {
  font-style: normal;
  color: var(--ember);
  font-variation-settings: "SOFT" 90, "WONK" 1;
}

@media (max-width: 620px) {
  .banner { letter-spacing: -0.02em; line-height: 1; }
}
h2 { font-size: clamp(1.75rem, 3.4vw, 2.6rem); margin-bottom: .75rem; }
h3 { font-size: 1.25rem; line-height: 1.3; }

p { max-width: var(--measure); }

.eyebrow {
  font-family: var(--label);
  font-size: .7rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--smoke);
  margin: 0 0 1.25rem;
}

.lede {
  font-family: var(--display);
  font-variation-settings: "SOFT" 60, "WONK" 1;
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  line-height: 1.45;
  max-width: 34ch;
}

/* ---------- shell ---------- */

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 var(--gut); }

.skip {
  position: absolute; left: -9999px;
  background: var(--ink); color: var(--ash); padding: .75rem 1rem;
}
.skip:focus { left: 1rem; top: 1rem; z-index: 50; }

/* ---------- nav ---------- */

.masthead {
  position: sticky; top: 0; z-index: 20;
  background: var(--espresso);
  border-bottom: 3px solid var(--red);
  color: var(--cream);
}
.masthead .wrap {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap;
  padding-top: 1.1rem; padding-bottom: 1.1rem;
}
.wordmark {
  color: var(--cream);
  display: inline-flex; align-items: center; gap: .8rem;
  line-height: 1.15;
  font-family: var(--display);
  font-variation-settings: "SOFT" 30, "WONK" 1;
  font-size: 1.2rem;
  letter-spacing: .01em;
  border: 0;
  white-space: nowrap;
}
.wordmark .chop {
  height: 38px; width: auto; flex: 0 0 auto;
  transition: transform .4s cubic-bezier(.2,.7,.2,1);
}
.wordmark:hover .chop { transform: rotate(-2deg); }
.wordmark .studio {
  display: block;
  font-family: var(--label);
  font-size: .6rem; letter-spacing: .22em; text-transform: uppercase;
  color: #FF5A55;
  margin-top: .25rem;
}
@media (max-width: 560px) {
  .wordmark .chop { height: 30px; }
  .wordmark .studio { font-size: .54rem; letter-spacing: .16em; }
}

/* The logo is a graphic, not a bullet point. Sized the way it was on
   the old site — around 300-375px — so it reads as a mark rather than
   an afterthought. White on the dark footer, ink on light ground. */
/* The footer logo is the sign-off — centred on its own line beneath
   the details, with room around it so it reads as a mark being set
   down rather than a graphic wedged into a column. */
.foot-logo {
  display: block;
  width: clamp(130px, 16vw, 175px);
  height: auto;
  margin: 3rem auto 0;
  opacity: .92;
}
/* the Contact page carries no logo of its own — the footer sits
   directly beneath it and already signs off */

nav ul { display: flex; gap: 1.6rem; list-style: none; margin: 0; padding: 0; flex-wrap: wrap; }
nav a {
  font-family: var(--label);
  font-size: .72rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--cream);
  border: 0;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
}
nav a:hover { border-bottom-color: var(--cream); }
nav a[aria-current="page"] { color: #FF5A55; border-bottom-color: #FF5A55; }

/* ---------- crack rule (signature) ----------
   A divider that fractures instead of ruling. The work is made by
   pushing clay until the surface splits; the page does the same.  */

.crack { display: block; width: 100%; height: 14px; margin: 4.5rem 0; overflow: visible; }
.crack path { fill: none; stroke: var(--ash-2); stroke-width: 1.25; }
.crack .flash { stroke: var(--red); stroke-width: 1.25; stroke-dasharray: 0 1000; }

/* ---------- hero ----------
   Stacked, not split. The name runs the width of the page, a short
   line of text sits beneath it at a readable measure, and the
   photograph gets the full width underneath at whatever proportions
   it actually has. A wide panoramic and a tall portrait both work
   without either one crushing the type.                            */

.hero { padding: clamp(2.5rem, 6vw, 5rem) 0 0; }
.hero .banner { margin-bottom: 2rem; position: relative; z-index: 2; }

.hero-intro {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(1.5rem, 5vw, 4rem);
  flex-wrap: wrap;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.hero-intro .lede { margin: 0; flex: 1 1 26ch; }
.hero-intro .meta-right {
  font-family: var(--label);
  font-size: .68rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--smoke); text-align: right; line-height: 2;
  flex: 0 1 auto;
}
@media (max-width: 700px) {
  .hero-intro { flex-direction: column; align-items: flex-start; }
  .hero-intro .meta-right { text-align: left; }
}

.hero-figure { position: relative; margin: 0; }
.hero-figure img {
  width: 100%;
  height: auto;
  max-height: 72vh;
  object-fit: contain;
  object-position: center;
  filter: saturate(.95) contrast(1.03);
}
/* ember bleeding out from behind the photograph */
.hero-figure::before {
  content: "";
  position: absolute; inset: 6% 4%;
  background: radial-gradient(closest-side, rgba(126,31,22,.22), transparent 70%);
  filter: blur(34px);
  z-index: -1;
}
.hero-figure figcaption {
  font-family: var(--label);
  font-size: .68rem;
  letter-spacing: .1em;
  color: var(--smoke);
  margin-top: .85rem;
  text-transform: uppercase;
}

/* ---------- sections ---------- */

.section { padding: clamp(2.5rem, 6vw, 4.5rem) 0; }

/* a warm band behind a section, edge to edge, so pages step between
   two grounds instead of running as one flat field */
.banded {
  background: var(--band);
  border-top: 1px solid var(--band-deep);
  border-bottom: 1px solid var(--band-deep);
}
.banded + .banded { border-top: 0; }

/* inside a band, panels and image wells need to step the other way or
   they vanish into the ground */
.banded .piece img,
.banded .filters button { background-color: var(--canvas); }

/* ---------- dark ground ----------
   The espresso used for the header and footer, used as a room. Work
   photographed on white reads far better against it — the same reason
   galleries paint a wall dark behind ceramics. Everything inside has
   to invert: labels, rules, controls.                               */

.dark {
  background: var(--espresso);
  color: var(--cream);
  border-top: 1px solid rgba(247,233,211,.14);
  border-bottom: 1px solid rgba(247,233,211,.14);
}
.dark .eyebrow,
.dark .rubric,
.dark .tomb { color: #C9A88E; }
.dark .tomb b { color: var(--cream); }
.dark p { color: #E4D2BC; }

.dark .filters button {
  border-color: rgba(247,233,211,.28);
  color: #C9A88E;
  background: none;
}
.dark .filters button:hover { border-color: var(--cream); color: var(--cream); }
.dark .filters button[aria-pressed="true"] {
  background: var(--cream); border-color: var(--cream); color: var(--ink);
}

.dark .piece img { background-color: #3A241B; }

.dark .rail-bar { border-top-color: rgba(247,233,211,.16); }
.dark .rail-btn { border-color: rgba(247,233,211,.28); color: var(--cream); }
.dark .rail-btn:hover { background: var(--cream); color: var(--ink); border-color: var(--cream); }
.dark .rail-btn[disabled]:hover { background: none; color: var(--cream); }
.dark .rail-btn.playing { border-color: var(--red); color: #FF5A55; }
.dark .rail-btn.playing:hover { background: var(--red); color: #fff; }
.dark .rail-track { background: rgba(247,233,211,.22); }
.dark .rail-count { color: #C9A88E; }

/* vertical rubric down the left margin, like a kiln shelf label */
.rubric {
  position: absolute; left: calc(var(--gut) * -1 + .35rem); top: 0;
  writing-mode: vertical-rl;
  font-family: var(--label); font-size: .62rem;
  letter-spacing: .3em; text-transform: uppercase;
  color: var(--smoke); opacity: .75;
}
@media (max-width: 1100px) { .rubric { display: none; } }
.section-tight { padding: clamp(1.5rem, 3vw, 2.5rem) 0; }

.two-col {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: clamp(1.5rem, 5vw, 4rem);
  align-items: start;
}
/* when the narrow column holds a photograph instead of a label it
   needs real width — 375px is what the old site used and it was right */
.two-col.with-figure { grid-template-columns: minmax(260px, 375px) 1fr; }

@media (max-width: 760px) {
  .two-col, .two-col.with-figure { grid-template-columns: 1fr; }
}

/* a feature image sits centred at a readable width rather than running
   the full 1180px of the page */
.feature { margin: 3.5rem auto 0; max-width: 768px; }

.prose p + p { margin-top: 1.15rem; }

/* a subhead inside running prose — marks a turn in the text without
   breaking the column or starting a new section */
.subhead {
  font-family: var(--label);
  font-size: .7rem;
  font-weight: 400;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--red-ink);
  margin: 2.25rem 0 .9rem;
}
.prose p:first-child { margin-top: 0; }

/* pull quote */
.pull::before {
  content: "\201C";
  display: block;
  font-family: var(--display);
  font-size: 4rem; line-height: .6;
  color: var(--ember); opacity: .35;
  margin-bottom: .5rem;
}
.pull {
  font-family: var(--display);
  font-variation-settings: "SOFT" 80, "WONK" 1;
  font-size: clamp(1.4rem, 2.8vw, 2rem);
  line-height: 1.3;
  max-width: 24ch;
  margin: 0;
  color: var(--ink);
  border-left: 2px solid var(--red);
  padding-left: 1.25rem;
}

/* ---------- gallery: carousel ----------
   A horizontal rail rather than a page of thumbnails. Every piece is
   sized by HEIGHT, so a tall figure and a wide vessel sit side by side
   at the same scale and neither one gets cropped to fit a box. The
   rail scroll-snaps, so it always comes to rest on a piece.          */

.carousel { position: relative; margin-top: 2rem; }

.rail {
  display: flex;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  padding: 0 0 1.5rem;
  /* let the rail run to the edge of the screen on the right so the
     next piece is visibly cut off — that's the cue that it scrolls */
  margin-right: calc(var(--gut) * -1);
  padding-right: var(--gut);
}
.rail::-webkit-scrollbar { display: none; }

/* snapping and drifting fight each other — while the rail is drifting
   on its own, snap is off; it comes back the moment you take over */
.rail.drifting { scroll-snap-type: none; scroll-behavior: auto; }
@media (prefers-reduced-motion: reduce) { .rail { scroll-behavior: auto; } }

.piece {
  flex: 0 0 auto;
  margin: 0;
  scroll-snap-align: center;
  max-width: 88vw;
}

.piece button {
  padding: 0; border: 0; background: none; cursor: zoom-in;
  display: block; position: relative; overflow: hidden;
  height: clamp(280px, 56vh, 560px);
}
.piece img {
  height: 100%;
  width: auto;
  max-width: 88vw;
  object-fit: contain;
  background: var(--ash-2);
  transition: transform .6s cubic-bezier(.2,.7,.2,1), filter .4s ease;
}
.piece button:hover img { transform: scale(1.02); filter: brightness(1.03); }

/* accession number, set like a catalogue index */
.piece .idx {
  position: absolute; top: .6rem; left: .6rem; z-index: 2;
  font-family: var(--label); font-size: .6rem; letter-spacing: .18em;
  color: var(--ash); mix-blend-mode: difference;
  opacity: 0; transition: opacity .35s ease;
}
.piece:hover .idx { opacity: .9; }

.piece button::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--red);
  transform: scaleX(0); transform-origin: left;
  transition: transform .5s cubic-bezier(.2,.7,.2,1);
}
.piece button:hover::after { transform: scaleX(1); }

/* tombstone label — the museum wall card. Mono, because this is data. */
.tomb {
  font-family: var(--label);
  font-size: .68rem;
  line-height: 1.55;
  color: var(--smoke);
  margin-top: .7rem;
  letter-spacing: .01em;
  max-width: 34ch;
}
.tomb b {
  display: block;
  font-family: var(--display);
  font-variation-settings: "SOFT" 50, "WONK" 1;
  font-weight: 400;
  font-size: 1.02rem;
  letter-spacing: 0;
  color: var(--ink);
  margin-bottom: .2rem;
}
.tomb .todo { color: var(--ember); opacity: .85; }

/* rail controls */
.rail-bar {
  display: flex; align-items: center; gap: 1rem;
  margin-top: 1.25rem;
  border-top: 1px solid var(--ash-2);
  padding-top: 1rem;
}
.rail-btn {
  background: none; border: 1px solid var(--ash-2); color: var(--ink);
  width: 42px; height: 42px; cursor: pointer;
  display: grid; place-items: center;
  font-size: 1rem; line-height: 1;
  transition: border-color .2s, background .2s, color .2s;
}
.rail-btn:hover { border-color: var(--ink); background: var(--ink); color: var(--ash); }
.rail-btn[disabled] { opacity: .3; cursor: default; }
.rail-btn[disabled]:hover { background: none; color: var(--ink); border-color: var(--ash-2); }

.rail-btn.playing { border-color: var(--red); color: var(--red-ink); }
.rail-btn.playing:hover { background: var(--red); color: #fff; border-color: var(--red); }

.rail-count {
  font-family: var(--label); font-size: .7rem;
  letter-spacing: .16em; color: var(--smoke);
  margin-left: auto;
}

/* progress line — fills as you move through the work */
.rail-track {
  flex: 1 1 120px; max-width: 260px;
  height: 1px; background: var(--ash-2); position: relative;
}
.rail-track i {
  position: absolute; left: 0; top: -1px; height: 3px;
  background: var(--red); width: 0;
  transition: width .25s ease, left .25s ease;
}

.filters { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: 1.5rem; }
.filters button {
  font-family: var(--label);
  font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
  background: none; border: 1px solid var(--ash-2); color: var(--smoke);
  padding: .5rem .9rem; cursor: pointer;
  transition: all .2s ease;
}
.filters button:hover { border-color: var(--smoke); color: var(--ink); }
.filters button[aria-pressed="true"] {
  background: var(--ink); border-color: var(--ink); color: var(--ash);
}

/* ---------- viewer ----------
   Full-bleed, dark, zoomable, swipeable. The work fills the screen and
   the chrome gets out of the way.                                    */

.viewer {
  position: fixed; inset: 0; z-index: 100;
  background: #12100B;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  overflow: hidden;
  /* 100vh on a phone means the height WITHOUT the address bar, which is
     taller than what you can actually see — the bottom of the picture
     ends up under the browser chrome. dvh is the real visible height. */
  height: 100vh;
  height: 100dvh;
  opacity: 0; visibility: hidden;
  transition: opacity .3s ease, visibility .3s;
}
.viewer.on { opacity: 1; visibility: visible; }

.v-bar {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  padding: 1rem clamp(1rem, 3vw, 2rem);
  color: var(--ash-2);
  font-family: var(--label); font-size: .7rem; letter-spacing: .14em;
  text-transform: uppercase;
}
.v-count { color: var(--smoke); }
.v-tools { display: flex; gap: .35rem; align-items: center; }

.v-btn {
  background: none; border: 1px solid rgba(230,220,203,.22);
  color: var(--ash-2); cursor: pointer;
  font-family: var(--label); font-size: .72rem; line-height: 1;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  transition: border-color .2s, color .2s, background .2s;
}
.v-btn:hover { border-color: var(--ash); color: #fff; }
.v-btn[disabled] { opacity: .3; cursor: default; }
.v-btn.wide { width: auto; padding: 0 .8rem; letter-spacing: .12em; }

/* stage */
.v-stage {
  position: relative; overflow: hidden;
  display: grid; place-items: center;
  touch-action: none;
  cursor: zoom-in;
  /* without these the row grows to fit the image instead of the image
     shrinking to fit the row, and tall pieces get their feet cut off */
  min-height: 0;
  min-width: 0;
}
.v-stage.zoomed { cursor: grab; }
.v-stage.zoomed.dragging { cursor: grabbing; }

/* The image is pinned to the stage box and told to fit inside it.
   It is sized BY the box rather than sizing the box, so it can never
   overflow no matter how large the source file is or how the rows
   resolve. object-fit: contain letterboxes it and keeps the aspect
   ratio honest. This replaces a chain of max-height rules that only
   worked if every link in it resolved correctly.                    */
.v-stage img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  padding: 0 clamp(1rem, 5vw, 4rem);
  transform-origin: center center;
  transition: transform .35s cubic-bezier(.2,.7,.2,1), opacity .25s ease;
  will-change: transform;
  user-select: none; -webkit-user-drag: none;
}
.v-stage.dragging img { transition: none; }
.v-stage img.loading { opacity: .25; }

/* the spinner is a kiln flame, not a wheel */
.v-loading {
  position: absolute; inset: 0; display: none; place-items: center;
  pointer-events: none;
}
.v-loading.on { display: grid; }
.v-loading span {
  width: 3px; height: 22px; background: var(--red);
  animation: flicker 1s ease-in-out infinite;
  transform-origin: bottom center;
}
@keyframes flicker {
  0%, 100% { transform: scaleY(.5) skewX(0deg); opacity: .55; }
  50%      { transform: scaleY(1) skewX(6deg);  opacity: 1; }
}

/* arrows sit over the stage edges */
.v-nav {
  position: absolute; top: 0; bottom: 0; width: clamp(56px, 8vw, 96px);
  background: none; border: 0; cursor: pointer;
  color: var(--ash-2); font-size: 1.6rem;
  display: grid; place-items: center;
  opacity: .45; transition: opacity .2s;
  z-index: 2;
}
.v-nav:hover { opacity: 1; }
.v-nav.prev { left: 0; }
.v-nav.next { right: 0; }
.v-stage.zoomed .v-nav { opacity: 0; pointer-events: none; }

/* caption + filmstrip */
.v-foot { padding: .5rem clamp(1rem, 3vw, 2rem) .9rem; min-height: 0; }

.v-cap {
  text-align: center;
  margin: 0;
  font-family: var(--label); font-size: .7rem; letter-spacing: .05em;
  color: var(--smoke); line-height: 1.6;
  min-height: 2.6rem;
}
.v-cap b {
  display: block;
  font-family: var(--display);
  font-variation-settings: "SOFT" 50, "WONK" 1;
  font-weight: 400; font-size: 1.2rem; letter-spacing: 0;
  color: var(--ash); margin-bottom: .15rem;
}
.v-cap .todo { color: var(--ember); }

.v-strip {
  display: flex; gap: .45rem; overflow-x: auto; padding: .7rem 0 .2rem;
  scrollbar-width: thin; scrollbar-color: rgba(230,220,203,.25) transparent;
  justify-content: flex-start;
}
.v-strip::-webkit-scrollbar { height: 4px; }
.v-strip::-webkit-scrollbar-thumb { background: rgba(230,220,203,.25); }
.v-strip button {
  flex: 0 0 auto; width: 44px; height: 44px;
  padding: 0; border: 0; background: #1E1A13; cursor: pointer;
  opacity: .38; transition: opacity .2s, box-shadow .2s;
}
.v-strip button:hover { opacity: .8; }
.v-strip button[aria-current="true"] {
  opacity: 1;
  box-shadow: inset 0 0 0 2px var(--red);
}
.v-strip img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 640px) {
  .v-strip { display: none; }
  .v-nav { width: 44px; opacity: .3; }
  .v-stage img { max-width: 100%; }
}

/* ---------- CV ---------- */

/* one compact strip: what the page is and how to take it away.
   The name is not repeated here — it is already in the masthead. */
.cv-head {
  display: flex; justify-content: space-between; align-items: center;
  gap: 1.25rem; flex-wrap: wrap;
}

/* and again at the end, for anyone who has read to the bottom */
.cv-foot {
  margin-top: 3.5rem;
  padding-top: 2rem;
  border-top: 1px solid var(--band-deep);
  text-align: center;
}
.cv-section { margin-top: 3rem; }
.cv-section > h2 {
  font-size: 1.15rem;
  font-family: var(--label);
  font-variation-settings: normal;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink);
  padding-bottom: .6rem;
  border-bottom: 1px solid var(--ash-2);
  margin-bottom: 1.25rem;
}
.cv-list { list-style: none; margin: 0; padding: 0; }
.cv-list li {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: 1.25rem;
  padding: .55rem 0;
  border-bottom: 1px solid rgba(200,188,166,.6);
  align-items: baseline;
}
.cv-list li:last-child { border-bottom: 0; }
.cv-list .yr {
  font-family: var(--label);
  font-size: .78rem;
  color: var(--smoke);
  letter-spacing: .04em;
  white-space: nowrap;
}
.cv-list .what { max-width: 68ch; }
.cv-list .what small { display: block; color: var(--smoke); font-size: .9rem; margin-top: .15rem; }
/* One emphasis device, one meaning: an italic run is always the name of
   an exhibition, workshop, or publication. Everything else stays plain.
   (Prefer bold? Change font-style: italic to font-weight: 700.)          */
.cv-list .what em {
  font-style: italic;
  font-weight: 400;
  color: var(--ink);
}
@media (max-width: 640px) {
  .cv-list li { grid-template-columns: 1fr; gap: .1rem; }
}

.cv-download {
  font-family: var(--label); font-size: .7rem; letter-spacing: .14em;
  text-transform: uppercase; border: 1px solid var(--ink); color: var(--ink);
  padding: .7rem 1.1rem; display: inline-block;
}
.cv-download:hover { background: var(--ink); color: var(--ash); border-color: var(--ink); }

/* ---------- contact ---------- */

.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 6vw, 4rem); align-items: start; }
@media (max-width: 760px) { .contact-grid { grid-template-columns: 1fr; } }

.contact-line {
  font-family: var(--display);
  font-variation-settings: "SOFT" 60, "WONK" 1;
  font-size: clamp(1.35rem, 3vw, 2rem);
  line-height: 1.4;
}
.meta { font-family: var(--label); font-size: .78rem; color: var(--smoke); letter-spacing: .04em; line-height: 2; }
.meta strong { display: block; color: var(--ink); letter-spacing: .16em; text-transform: uppercase; font-size: .68rem; margin-top: 1.25rem; font-weight: 400; }

/* ---------- footer ---------- */

footer {
  background: var(--kiln);
  color: #CFC3AE;
  margin-top: 5rem;
  padding: 3.5rem 0 2.5rem;
}
footer a { color: var(--ash); border-bottom-color: rgba(230,220,203,.32); }
footer a:hover { color: #fff; border-bottom-color: #fff; }
.foot-grid { display: flex; justify-content: space-between; gap: 2rem 3rem; flex-wrap: wrap; align-items: start; }
.foot-mark {
  font-family: var(--display);
  font-variation-settings: "SOFT" 40, "WONK" 1;
  font-size: 1.4rem; color: var(--ash);
}
.foot-meta { font-family: var(--label); font-size: .72rem; letter-spacing: .06em; line-height: 2; }
.colophon {
  margin-top: 2.5rem; padding-top: 1.5rem;
  border-top: 1px solid rgba(230,220,203,.16);
  font-family: var(--label); font-size: .65rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--smoke);
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
}


/* ============================================================
   QUIET MODE
   Everything below strips the decorative layer back: no paper
   grain, no kiln bloom, no fractured dividers, no margin
   rubrics, no accession numbers, smaller headings. Structure,
   spacing, colour, and every feature stay exactly as they are —
   only the flourishes go.

   Switch it in build.py:  STYLE = "quiet"  or  STYLE = "full"
   ============================================================ */

body.quiet::before,
body.quiet::after { display: none; }

body.quiet .rubric { display: none; }
body.quiet .piece .idx { display: none; }
body.quiet .piece button::after { display: none; }

/* dividers become a plain hairline */
body.quiet .crack { height: 1px; margin: 3rem 0; background: var(--ash-2); }
body.quiet .crack path { display: none; }

/* headings sit at a normal editorial size instead of spanning the page */
body.quiet .banner {
  font-size: clamp(2rem, 4.4vw, 3.2rem) !important;
  line-height: 1.05;
  text-indent: 0;
}
body.quiet .banner .row { white-space: normal; display: inline; }
body.quiet .banner em { color: var(--ink); }

/* keep the ember for links and controls, drop it as decoration */
body.quiet .pull { border-left-color: var(--ash-2); }
body.quiet .pull::before { color: var(--ash-2); }
body.quiet .hero-figure::before { display: none; }
body.quiet .hero-figure { margin-top: 0; }
