/* ==========================================================================
   305 Rick Art: design system v2, "The white wall"
   A white gallery where the paintings supply every colour. The site itself
   contributes paper, ink, and one fixed brand orange used as a fill only.
   Everything else on screen is measured out of the actual canvases via
   --piece-* custom properties, scoped per element, never at :root.
   ========================================================================== */

/* ---- Fonts (self-hosted, no network call) ------------------------------ */
@font-face {
  font-family: "Anton";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/anton-400.woff2") format("woff2");
}
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/archivo-variable.woff2") format("woff2-variations"), url("../fonts/archivo-variable.woff2") format("woff2");
}
@font-face {
  font-family: "Fredericka the Great";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/fredericka-400.woff2") format("woff2");
}

/* ---- Tokens -------------------------------------------------------------- */
:root {
  /* ground and surfaces */
  --paper: #FAF9F6;
  --paper-2: #F1EFE9;
  --white: #FFFFFF;
  --ink: #121216;
  --ink-soft: #5B5B66;
  --line: #DEDBD2;

  /* the one fixed brand colour: fill only, never text on paper (2.3:1) */
  --orange: #FF7A00;

  /* impact section only: the one dark ground on the site */
  --lime: #C0FF73;

  /* page-level scroll-linked accent (signature move 3.5). This is the single
     exception to "never at :root": --piece-* custom properties stay scoped to
     their element, but --accent is explicitly a page-level token that a
     section-level IntersectionObserver retargets as the user scrolls. */
  --accent: var(--ink);

  /* type */
  --font-display: "Anton", "Arial Narrow", sans-serif;
  --font-body: "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-signature: "Fredericka the Great", cursive;

  /* scale */
  --radius: 10px;
  --radius-sm: 6px;
  --container: 1200px;
  --gutter: 20px;

  /* shadows tinted to the paper hue, never pure black on a light ground */
  --shadow-card: 0 10px 26px rgb(18 18 22 / 0.08);
  --shadow-lift: 0 22px 44px rgb(18 18 22 / 0.16);

  color-scheme: light;
}

/* ---- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html {
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
}
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  min-height: 100vh;
  min-height: 100svh;
}
img, picture, svg { max-width: 100%; display: block; }

/* A <picture> is a real box in the layout. An <img> inside it with height:100%
   resolves that percentage against the <picture>, not against the styled
   container, so any fill/cover image wrapped in <picture> overflows unless the
   wrapper is stretched too. Every fixed-aspect image container on this site is
   listed here; add new ones to this selector, not a one-off rule elsewhere. */
.hero-media picture,
.about-strip-portrait picture,
.product-card-media picture,
.product-media-main picture,
.thumb-btn picture,
.salon-frame picture,
.detail-band picture,
.portrait-band picture,
.process-strip-tile picture,
.cause-card-media picture,
.album-card-media picture,
.giving-row-media picture,
.timeline-row-media picture,
.commission-row-media picture,
.lightbox-media picture { display: block; width: 100%; height: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p, figure { margin: 0; }
label { display: block; }
input, textarea, select { font: inherit; }

/* Numbers */
.tnum { font-variant-numeric: tabular-nums; }

/* ---- Layout helpers -------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.section {
  padding-block: clamp(48px, 8vw, 96px);
}
.section-tight { padding-block: clamp(32px, 5vw, 56px); }

.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  background: var(--orange);
  color: #150900;
  font-weight: 700;
  padding: 12px 18px;
  border-radius: var(--radius-sm);
  z-index: 1000;
  transition: top .2s ease;
}
.skip-link:focus {
  top: 12px;
}

/* ---- Typography ------------------------------------------------------------ */
h1, h2, h3, .display {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 1.02;
  text-wrap: balance;
  font-weight: 400;
}
/* v3 vibrancy pass: bigger display type, tighter tracking. Anton can take it. */
h1 { font-size: clamp(2.8rem, 9.5vw, 5.6rem); letter-spacing: -0.03em; }
h2 { font-size: clamp(2rem, 6vw, 3.4rem); letter-spacing: -0.02em; }
h3 { font-size: clamp(1.3rem, 3.4vw, 1.7rem); }

p { max-width: 65ch; }
.lede { font-size: 1.15rem; color: var(--ink-soft); }
.eyebrow {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.signature {
  font-family: var(--font-signature);
  font-weight: 400;
  font-size: 1.8rem;
  line-height: 1.2;
  color: var(--ink);
  padding-bottom: 0.15em;
}

/* ---- Knockout display type (signature move 3.2) ---------------------------
   Real paint filled into real, selectable text. Used on the homepage H1 and
   exactly two other headings, always 2.5rem and above, never on body copy or
   a link. Three fallbacks below: no background-clip support, Windows forced
   colours, and the accessibility widget's own contrast mode. */
.knockout {
  background-size: cover;
  background-position: center;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .knockout {
    color: var(--ink);
    background-image: none !important;
    -webkit-text-fill-color: initial;
  }
}
@media (forced-colors: active) {
  .knockout {
    color: CanvasText;
    background-image: none !important;
    -webkit-text-fill-color: initial;
  }
}
html.a11y-contrast .knockout {
  color: var(--ink);
  background-image: none !important;
  -webkit-text-fill-color: initial;
}

/* ---- Buttons ---------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 26px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 0.95rem;
  border: 2px solid transparent;
  cursor: pointer;
  background: var(--paper-2);
  color: var(--ink);
  transition: transform .18s cubic-bezier(.32,.72,0,1), background-color .18s ease, border-color .18s ease, box-shadow .18s ease, filter .18s ease;
  white-space: nowrap;
}
.btn:active { transform: scale(0.98); }
@media (prefers-reduced-motion: reduce) {
  .btn { transition: background-color .18s ease, border-color .18s ease; }
  .btn:active { transform: none; }
}
.btn-primary {
  background: var(--orange);
  border-color: var(--orange);
  color: #150900;
}
.btn-primary:hover, .btn-primary:focus-visible { background: #ff8c1f; border-color: #ff8c1f; }
.btn-outline {
  background: transparent;
  border-color: var(--ink-soft);
  color: var(--ink);
}
.btn-outline:hover, .btn-outline:focus-visible { border-color: var(--ink); background: var(--paper-2); }
.btn-pill-small {
  padding: 9px 18px;
  font-size: 0.82rem;
  background: var(--orange);
  border-color: var(--orange);
  color: #150900;
}
.btn-pill-small:hover, .btn-pill-small:focus-visible { background: #ff8c1f; }
.btn-block { width: 100%; }
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--paper-2);
  border-color: var(--line);
  color: var(--ink-soft);
  cursor: not-allowed;
}
.btn:disabled:hover, .btn[aria-disabled="true"]:hover { transform: none; }

/* Inside a themed product page, the primary action carries the piece's own
   colour (signature move 3.1). Scoped to .piece-theme so no other page's
   buttons are touched. */
.piece-theme .btn-primary {
  background: var(--piece-accent, var(--orange));
  border-color: var(--piece-accent, var(--orange));
  color: var(--piece-ink, #150900);
}
.piece-theme .btn-primary:hover, .piece-theme .btn-primary:focus-visible {
  filter: brightness(1.08);
}

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

/* ---- Header ------------------------------------------------------------------ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 500;
  background: rgb(250 249 246 / 0.9);
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  border-bottom: 1px solid var(--line);
}
/* The scroll-linked accent ribbon (signature move 3.5): a slim strip under
   the header hairline that retargets colour as the art on screen changes. */
.site-header {
  position: sticky;
}
.site-header::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--accent);
  transition: background-color .5s ease;
}
@media (prefers-reduced-motion: reduce) {
  .site-header::after { transition: none; }
}
.site-header .wrap {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: 68px;
}
.brand-link {
  display: flex;
  align-items: center;
  height: 100%;
  flex: 0 1 auto;
  min-width: 0;
}
.brand-wordmark { height: clamp(34px, 3.4vw, 46px); width: auto; display: block; }
.brand-tile { height: 36px; width: 36px; display: none; }

.main-nav {
  display: none;
}
.main-nav ul {
  display: flex;
  align-items: center;
  gap: 26px;
}
.main-nav a {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ink-soft);
  padding: 8px 2px;
  border-bottom: 2px solid transparent;
}
.main-nav a:hover, .main-nav a:focus-visible, .main-nav a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}
.ig-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 999px;
  color: var(--ink-soft);
  border: 1px solid var(--line);
  background: var(--white);
}
.ig-link:hover, .ig-link:focus-visible { color: var(--ink); border-color: var(--ink-soft); }
.ig-link svg { width: 19px; height: 19px; }

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: var(--radius-sm);
  background: var(--paper-2);
  border: 1px solid var(--line);
}
.nav-toggle svg { width: 20px; height: 20px; }
.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded="true"] .icon-open { display: none; }
.nav-toggle[aria-expanded="true"] .icon-close { display: block; }

.mobile-nav {
  position: fixed;
  inset: 68px 0 0 0;
  z-index: 490;
  background: var(--paper);
  padding: 24px var(--gutter) 40px;
  overflow-y: auto;
  display: none;
}
.mobile-nav.is-open { display: block; }
.mobile-nav ul { display: flex; flex-direction: column; gap: 4px; }
.mobile-nav a {
  display: block;
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 1.6rem;
  padding: 14px 4px;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
}
.mobile-nav a[aria-current="page"] { border-bottom-color: var(--ink); font-weight: 700; }
.mobile-nav .mobile-cta { margin-top: 24px; display: flex; flex-direction: column; gap: 12px; }
.mobile-nav .ig-link { margin-top: 20px; }

@media (min-width: 860px) {
  .main-nav { display: block; }
  .nav-toggle { display: none; }
  .mobile-nav { display: none !important; }
  .brand-tile { display: none; }
}
@media (max-width: 859.98px) {
  .header-cta-pill { display: none; }
}
@media (max-width: 420px) {
  .brand-wordmark { display: none; }
  .brand-tile { display: block; }
}

/* ---- Footer -------------------------------------------------------------------- */
.site-footer {
  background: var(--paper-2);
  border-top: 1px solid var(--line);
  padding-block: 56px 32px;
}
.footer-grid {
  display: grid;
  gap: 36px;
  grid-template-columns: 1fr;
}
@media (min-width: 700px) {
  .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; }
}
.footer-brand .brand-wordmark { height: 40px; margin-bottom: 16px; }
.footer-blurb { color: var(--ink-soft); font-size: 0.95rem; max-width: 40ch; }
.footer-col h4 {
  font-family: var(--font-body);
  text-transform: uppercase;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  margin-bottom: 14px;
  font-weight: 700;
}
.footer-col ul { display: flex; flex-direction: column; gap: 10px; }
.footer-col a { color: var(--ink); font-size: 0.95rem; }
.footer-col a:hover, .footer-col a:focus-visible { text-decoration: underline; text-underline-offset: 2px; }
.footer-bottom {
  margin-top: 44px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  align-items: center;
  justify-content: space-between;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

/* ---- Fade-up reveal (specificity-matched, gated on html.js) --------------------- */
html.js .fade-up {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .7s cubic-bezier(.32,.72,0,1), transform .7s cubic-bezier(.32,.72,0,1);
}
html.js .fade-up.is-in {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  html.js .fade-up {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---- Hero ------------------------------------------------------------------------ */
.hero {
  position: relative;
  min-height: 640px;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--paper);
}
.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 65% center;
}
/* Mobile: the photo sits in its own contained frame above the type, which now
   sits on solid paper, so the old full-bleed scrim is dropped entirely. A
   hairline separates photo from type instead of darkening the photo. */
.hero {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.hero-media {
  position: relative;
  inset: auto;
  aspect-ratio: 4 / 5;
  border-bottom: 1px solid var(--line);
}
.hero-content {
  position: relative;
  z-index: 2;
  width: 100%;
  padding-block: 32px clamp(32px, 8vw, 56px);
  background: var(--paper);
}
.hero .eyebrow { color: var(--ink-soft); margin-bottom: 14px; }
.hero h1 { margin-bottom: 16px; }
.hero .hero-sub {
  color: var(--ink-soft);
  font-size: 1.05rem;
  max-width: 52ch;
  margin-bottom: 26px;
}
.hero-ctas { display: flex; flex-wrap: wrap; gap: 14px; }

/* Desktop: the two-column split from v1, kept because it solved a real
   legibility problem. Type sits on solid paper, photo gets its own
   uncropped column with a hairline gutter so it does not float on white. */
@media (min-width: 860px) {
  .hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    align-items: stretch;
    min-height: 640px;
    min-height: 92svh;
  }
  .hero-media {
    aspect-ratio: auto;
    grid-column: 2;
    grid-row: 1;
    border-bottom: none;
    border-left: 1px solid var(--line);
  }
  .hero-media img { object-position: 52% 26%; }
  .hero-content {
    grid-column: 1;
    grid-row: 1;
    align-self: center;
    max-width: none;
    margin-inline: 0;
    padding-block: clamp(48px, 6vw, 88px);
    padding-inline-start: max(var(--gutter), calc((100vw - var(--container)) / 2 + var(--gutter)));
    padding-inline-end: clamp(28px, 4vw, 64px);
  }
  .hero .hero-sub { max-width: 46ch; }
}

/* ---- Stats bar (v3: a colour band, not a grey strip) ------------------------------
   Each stat takes a real piece's accent (set inline as --stat-accent/--stat-wash
   by statStyleAttr() in build.mjs), so the strip itself reads as three blocks
   of colour instead of one flat tint. */
.stats-bar {
  background: var(--paper-2);
  border-block: 1px solid var(--line);
}
.stats-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  padding-block: 28px;
}
.stat {
  text-align: left;
  padding: 18px 20px 16px;
  border-radius: var(--radius-sm);
  background: var(--stat-wash, transparent);
  border-top: 5px solid var(--stat-accent, var(--ink));
}
.stat .value {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5.6vw, 2.7rem);
  color: var(--stat-accent, var(--ink));
  line-height: 1;
}
.stat .label { color: var(--ink); font-weight: 600; font-size: 0.92rem; margin-top: 8px; }
.stat .qualifier { color: var(--ink-soft); font-size: 0.76rem; opacity: 0.85; margin-top: 2px; }
@media (min-width: 700px) {
  .stats-grid { grid-template-columns: repeat(3, 1fr); gap: 20px; }
}

/* ---- Section heading blocks -------------------------------------------------------- */
.section-head { margin-bottom: clamp(24px, 4vw, 40px); }
.section-head .eyebrow { margin-bottom: 10px; }
.section-head p { color: var(--ink-soft); margin-top: 14px; }
.section-head-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
}

/* ---- Accent rule: a short bar under a page-hero, retargeted the same way as
   the header ribbon (signature move 3.5). v3: thickened from 3px to 5px per
   the vibrancy pass ("section rules get thicker, 4px to 6px"). ---------------- */
.accent-rule {
  width: 64px;
  height: 5px;
  border: 0;
  border-radius: 2px;
  margin: 18px 0 0;
  background: var(--accent);
  transition: background-color .5s ease;
}
@media (prefers-reduced-motion: reduce) {
  .accent-rule { transition: none; }
}

/* A full-width version of the same thick rule, used at section boundaries
   rather than only under a page-hero (v3 vibrancy pass, spec section 2). */
.section-rule {
  width: 100%;
  height: 5px;
  border: 0;
  border-radius: 2px;
  margin: 0 0 clamp(28px, 5vw, 48px);
  background: var(--piece-accent, var(--accent));
}

/* ---- Vibrancy pass: alternating grounds + the one vivid block per page ------------
   Scrolling should feel like moving through rooms, not down a document. Ground
   utilities cycle a page between --paper, a piece's --piece-wash (set inline by
   pieceStyleAttr()), and --paper-2. .vivid-block is the one full-bleed colour
   fill per page: --piece-vivid for the fill, --piece-ink for every bit of text
   inside it, per the contrast rule that never moves (--piece-accent is for text,
   --piece-vivid is a fill colour only). */
.ground-paper { background: var(--paper); }
.ground-paper-2 { background: var(--paper-2); }
.ground-wash { background: var(--piece-wash, var(--paper-2)); }

.vivid-block {
  background: var(--piece-vivid, var(--orange));
  color: var(--piece-ink, #150900);
}
.vivid-block .eyebrow,
.vivid-block h1,
.vivid-block h2,
.vivid-block h3,
.vivid-block p,
.vivid-block cite,
.vivid-block blockquote { color: inherit; }
.vivid-block .eyebrow { opacity: 0.82; }
.vivid-block :focus-visible { outline-color: var(--piece-ink, #150900); }
/* A button inside a vivid block always uses a paper fill with ink text rather
   than trying to invert the piece's own accent pairing: guaranteed contrast
   regardless of which piece is behind it, and it reads as a clear "pop" card
   against a full colour field. */
.vivid-block .btn-primary,
.vivid-block .btn-outline {
  background: var(--paper);
  border-color: var(--paper);
  color: var(--ink);
}
.vivid-block .btn-primary:hover,
.vivid-block .btn-primary:focus-visible,
.vivid-block .btn-outline:hover,
.vivid-block .btn-outline:focus-visible {
  background: var(--white);
  border-color: var(--white);
}

/* ---- Full-bleed detail bands (signature move 3.3) ----------------------------------
   Extreme brushwork close-ups between major sections. Full bleed regardless of
   the page container, height clamped, text never sits on top of the paint. */
.detail-band {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  height: clamp(150px, 22vw, 320px);
  overflow: hidden;
  position: relative;
  background: var(--paper-2);
}
.detail-band img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
.detail-band-caption {
  margin-top: 10px;
  font-size: 0.78rem;
  color: var(--ink-soft);
  text-align: right;
}
.detail-band-caption a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.detail-band-caption a:hover, .detail-band-caption a:focus-visible { color: var(--ink-soft); }

/* ---- Salon wall (homepage signature) ------------------------------------------------- */
.salon-wall {
  background: var(--paper);
}
/* A dense, even hang. Mixed column spans were tried first, sized off each real
   canvas, and they produced holes in the grid and wild scale jumps because the
   source photos vary so much. Even squares at tight gutters read as a wall of
   work; the shadows and the hover lift carry the "hanging" feel instead. */
.salon-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
@media (min-width: 560px) {
  .salon-grid { grid-template-columns: repeat(3, 1fr); gap: 12px; }
}
@media (min-width: 900px) {
  .salon-grid { grid-template-columns: repeat(4, 1fr); gap: 14px; }
}
@media (min-width: 1200px) {
  .salon-grid { grid-template-columns: repeat(5, 1fr); }
}
.salon-tile {
  position: relative;
  display: block;
  border-radius: 3px;
  overflow: visible;
}
/* Per-piece theming (3.1) + pointer-reactive wall (3.6). White mat, a thin
   --line border so photography does not bleed into the paper ground. On
   hover (desktop, fine pointer only) and on keyboard focus (everywhere),
   the mat border becomes the piece's own accent and a soft wash glow lifts
   behind it. Neighbouring tiles never dim. */
.salon-frame {
  position: relative;
  border-radius: 3px;
  overflow: hidden;
  background: var(--paper-2);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
  transition: transform .35s cubic-bezier(.32,.72,0,1), box-shadow .35s cubic-bezier(.32,.72,0,1), border-color .35s ease;
}
/* Square frames on purpose. Rick's product photos mix flat front-on shots with
   canvases on easels in the studio, so honouring each photo's real aspect made
   the wall read as a camera roll. A uniform square crop puts the artwork in the
   frame and pushes the studio out of it. Tile SIZE still varies by his real
   canvas dimensions, which is what an actual salon hang does. */
.salon-frame {
  /* display:block is load-bearing. .salon-frame is a <span>, and aspect-ratio
     is ignored on non-replaced inline elements, so without this the square
     never applies and the tile falls back to each photo's natural aspect,
     which is exactly the camera-roll look the square crop exists to prevent.
     The percentage height on the inner <picture> cannot resolve either. */
  display: block;
  aspect-ratio: 1;
}
.salon-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.salon-tile:focus-visible .salon-frame {
  transform: translateY(-6px) scale(1.015);
  box-shadow: 0 20px 40px -10px var(--piece-wash, rgb(18 18 22 / 0.25));
  border-color: var(--piece-accent, var(--ink));
  outline: 3px solid var(--piece-accent, var(--ink));
  outline-offset: 3px;
}
@media (hover: hover) and (pointer: fine) {
  .salon-tile:hover .salon-frame {
    transform: translateY(-6px) scale(1.015);
    box-shadow: 0 20px 40px -10px var(--piece-wash, rgb(18 18 22 / 0.25));
    border-color: var(--piece-accent, var(--ink));
  }
}
@media (prefers-reduced-motion: reduce) {
  .salon-frame { transition: box-shadow .35s ease, border-color .35s ease; }
  .salon-tile:hover .salon-frame, .salon-tile:focus-visible .salon-frame { transform: none; }
}
.salon-meta {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 10px 10px 8px;
  background: linear-gradient(180deg, transparent, rgb(0 0 0 / 0.82) 60%);
  color: #fff;
  opacity: 1;
  transform: none;
  transition: opacity .25s ease;
}
.salon-meta .t { font-weight: 700; font-size: 0.82rem; line-height: 1.25; }
.salon-meta .m { font-size: 0.74rem; color: rgb(255 255 255 / 0.82); margin-top: 2px; display: flex; gap: 6px; flex-wrap: wrap; }
.salon-meta .m .price { color: var(--piece-vivid, #fff); font-weight: 700; }
@media (min-width: 700px) {
  .salon-meta { opacity: 0; transform: translateY(6px); transition: opacity .25s ease, transform .25s ease; }
  .salon-tile:hover .salon-meta, .salon-tile:focus-visible .salon-meta { opacity: 1; transform: none; }
}
.salon-footer-link {
  margin-top: 32px;
  text-align: center;
}
.salon-footer-link a {
  font-weight: 700;
  color: var(--ink);
  border-bottom: 1px solid var(--line);
}
.salon-footer-link a:hover, .salon-footer-link a:focus-visible { border-bottom-color: var(--ink); }

/* ---- Impact (the one dark section on the site) --------------------------------------
   Every other section is paper. This one inverts on purpose: it is the visual
   pause, and lime on near-black clears roughly 14:1, which it never did on
   white. */
.impact-section {
  background: var(--ink);
  color: #EDEDF0;
}
.impact-section p { color: #C7C7CF; }
.impact-section .eyebrow { color: var(--lime); }
.impact-section :focus-visible { outline-color: var(--lime); }

.impact-section .btn-outline {
  color: #fff;
  border-color: rgb(255 255 255 / 0.5);
  background: transparent;
}
.impact-section .btn-outline:hover,
.impact-section .btn-outline:focus-visible {
  border-color: var(--lime);
  background: var(--lime);
  color: #0B0F02;
}
.impact-total {
  font-family: var(--font-display);
  font-size: clamp(3.4rem, 12vw, 6rem);
  line-height: 0.95;
  color: var(--lime);
}
.impact-total-label { color: #C7C7CF; font-size: 1rem; margin-top: 6px; }
.impact-total-qualifier { color: #9A9AA6; font-size: 0.8rem; }
.impact-grid {
  display: grid;
  gap: 40px;
  margin-top: 40px;
}
@media (min-width: 860px) {
  .impact-grid { grid-template-columns: 1fr 1fr; align-items: start; }
}
.impact-quote {
  border-left: 4px solid var(--lime);
  padding-left: 20px;
  font-size: 1.2rem;
  line-height: 1.5;
}
.impact-quote cite {
  display: block;
  margin-top: 12px;
  font-style: normal;
  font-size: 0.85rem;
  color: #9A9AA6;
}
.cause-list { display: flex; flex-direction: column; gap: 10px; margin-top: 18px; }
.cause-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: rgb(255 255 255 / 0.06);
  border: 1px solid rgb(255 255 255 / 0.16);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 0.85rem;
  font-weight: 600;
  color: #EDEDF0;
  width: fit-content;
}
.cause-chip::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--lime);
}
.impact-cta { margin-top: 28px; }

/* Standalone /impact/ page: same dark ground as the homepage block, so a
   click-through does not land somewhere visually unrelated. Judgment call:
   the redesign spec names "Impact" as the one dark section without
   distinguishing the homepage teaser from the full page; treating the whole
   page as the site's other dark surface keeps the story coherent. */
body.page-impact { background: var(--ink); color: #EDEDF0; }
body.page-impact .eyebrow { color: var(--lime); }
body.page-impact h1 { color: #fff; }
body.page-impact .lede,
body.page-impact p { color: #C7C7CF; }
body.page-impact .impact-total { color: var(--lime); }
body.page-impact .impact-total-label { color: #C7C7CF; }
body.page-impact .impact-total-qualifier { color: #9A9AA6; }
body.page-impact .pull-quote { border-left-color: var(--lime); color: #E4E4E8; }
body.page-impact .pull-quote cite { color: #9A9AA6; }
body.page-impact h2 { color: #fff; }
body.page-impact .donation-row {
  background: rgb(255 255 255 / 0.05);
  border-color: rgb(255 255 255 / 0.16);
}
body.page-impact .donation-row .amount { color: var(--lime); }
body.page-impact .donation-row .meta,
body.page-impact .donation-row .date { color: #B4B4BE; }
body.page-impact .btn-outline {
  border-color: rgb(255 255 255 / 0.5);
  color: #fff;
}
body.page-impact .btn-outline:hover,
body.page-impact .btn-outline:focus-visible {
  border-color: var(--lime);
  background: var(--lime);
  color: #0B0F02;
}
body.page-impact .accent-rule { background: var(--lime); }
body.page-impact :focus-visible { outline-color: var(--lime); }
body.page-impact .detail-band { background: #000; }
body.page-impact .detail-band-caption { color: #9A9AA6; }
body.page-impact .detail-band-caption a { color: #EDEDF0; }

/* ---- About strip ------------------------------------------------------------------------ */
.about-strip {
  background: var(--paper-2);
}
.about-strip-grid {
  display: grid;
  gap: 28px;
  align-items: center;
}
@media (min-width: 780px) {
  .about-strip-grid { grid-template-columns: 220px 1fr; gap: 44px; }
}
.about-strip-portrait {
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 4 / 5;
  max-width: 260px;
  border: 1px solid var(--line);
}
.about-strip-portrait img { width: 100%; height: 100%; object-fit: cover; }
.about-strip-body p { color: var(--ink-soft); margin-top: 14px; }
.about-strip-body .btn { margin-top: 20px; }

/* ---- Commissions band ----------------------------------------------------------------------
   v3: always paired with .vivid-block in the markup, which now owns the
   background fill and the text colour (--piece-vivid / --piece-ink). This
   rule only owns layout, padding coming from .vivid-block's own padding
   is not set there so give it one here. */
.commissions-band { padding-block: clamp(48px, 8vw, 88px); }
.commissions-band .wrap {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: flex-start;
}
@media (min-width: 780px) {
  .commissions-band .wrap { flex-direction: row; align-items: center; justify-content: space-between; }
  .commissions-band h2 { max-width: 14ch; }
  .commissions-band .band-copy { max-width: 46ch; }
}

/* ---- Category chips ------------------------------------------------------------------------- */
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.chip {
  display: inline-flex;
  align-items: center;
  padding: 9px 18px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--ink-soft);
  font-weight: 600;
  font-size: 0.88rem;
  background: var(--white);
}
.chip:hover, .chip:focus-visible { color: var(--ink); border-color: var(--ink-soft); }
/* Category chips take the accent of the first piece in that category (3.1),
   set inline as --piece-accent / --piece-ink on the element itself. The "All"
   chip carries no piece and falls back to a neutral ink fill. */
.chip[aria-current="page"] {
  background: var(--piece-accent, var(--ink));
  border-color: var(--piece-accent, var(--ink));
  color: var(--piece-ink, #fff);
}

/* ---- Product / gallery grid (shop pages) ------------------------------------------------------ */
.gallery-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}
@media (min-width: 560px) {
  .gallery-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 900px) {
  .gallery-grid { grid-template-columns: repeat(3, 1fr); }
}
/* Per-piece theming on the shop card (3.1): white card, thin line border,
   hover/focus swap the border to the piece accent, add a soft wash-tinted
   lift, and flip the price to the piece accent. */
.product-card {
  display: block;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform .3s cubic-bezier(.32,.72,0,1), border-color .3s ease, box-shadow .3s ease;
}
.product-card:hover, .product-card:focus-visible {
  transform: translateY(-4px);
  border-color: var(--piece-accent, var(--ink-soft));
  box-shadow: 0 16px 32px -12px var(--piece-wash, rgb(18 18 22 / 0.2));
}
@media (prefers-reduced-motion: reduce) {
  .product-card:hover, .product-card:focus-visible { transform: none; }
}
.product-card-media { aspect-ratio: 1; background: var(--paper-2); overflow: hidden; }
.product-card-media img { width: 100%; height: 100%; object-fit: cover; }
.product-card-body { padding: 16px 18px 20px; }
.product-card-tag {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 8px;
}
.product-card-title { font-family: var(--font-body); font-weight: 700; font-size: 1.05rem; line-height: 1.3; color: var(--ink); }
.product-card-size { color: var(--ink-soft); font-size: 0.82rem; margin-top: 4px; }
.product-card-price { color: var(--ink); font-weight: 700; margin-top: 8px; font-size: 1.05rem; transition: color .2s ease; }
.product-card:hover .product-card-price, .product-card:focus-visible .product-card-price { color: var(--piece-accent, var(--ink)); }
.product-card-excerpt { color: var(--ink-soft); font-size: 0.86rem; margin-top: 10px; line-height: 1.5; }

/* ---- Product detail page ------------------------------------------------------------------------ */
/* The whole page themes (3.1): this wraps everything below the header in the
   product's own --piece-* custom properties, scoped to the element, never
   :root. Price, rules, the active thumbnail ring, spec bullets, links, and
   the reserve button all read from it. */
.piece-theme { background: var(--paper); }

.product-detail {
  display: grid;
  gap: 32px;
}
@media (min-width: 900px) {
  .product-detail { grid-template-columns: 1.1fr 1fr; gap: 56px; align-items: start; }
}
/* A large soft radial in the piece's wash sits behind the gallery, per 3.1.
   An absolutely positioned pseudo-element carries the glow past the image
   edge without adding to the box model, so it never widens the layout (a
   negative margin here previously pushed 2px past the viewport at 390px). */
.product-gallery {
  position: relative;
  isolation: isolate;
}
.product-gallery::before {
  content: "";
  position: absolute;
  inset: -22px;
  z-index: -1;
  border-radius: 26px;
  background: radial-gradient(ellipse at 32% 24%, var(--piece-wash, transparent), transparent 65%);
  pointer-events: none;
}
.product-media-main {
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper-2);
  border: 1px solid var(--line);
  aspect-ratio: 4 / 5;
}
.product-media-main img { width: 100%; height: 100%; object-fit: cover; }
.thumb-strip { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.thumb-btn {
  width: 68px;
  height: 68px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 2px solid var(--line);
  background: var(--paper-2);
  padding: 0;
  cursor: pointer;
}
.thumb-btn img { width: 100%; height: 100%; object-fit: cover; }
.thumb-btn.is-active { border-color: var(--piece-accent, var(--ink)); }
.thumb-btn:hover, .thumb-btn:focus-visible { border-color: var(--ink-soft); }

.product-info-tag {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 10px;
}
.product-info h1 { font-size: clamp(1.8rem, 4.4vw, 2.6rem); margin-bottom: 8px; color: var(--ink); }
.product-info .size { color: var(--ink-soft); margin-bottom: 6px; }
.product-info .price {
  font-family: var(--font-display);
  font-size: 1.9rem;
  color: var(--piece-accent, var(--ink));
  margin-bottom: 12px;
}
.piece-rule {
  height: 5px;
  width: 56px;
  border: 0;
  border-radius: 2px;
  background: var(--piece-accent, var(--ink));
  margin: 0 0 20px;
}
.product-story { margin: 22px 0; display: flex; flex-direction: column; gap: 12px; }
.product-story p { color: var(--ink-soft); max-width: 60ch; }

.variant-group { margin-bottom: 18px; }
.variant-group legend {
  font-weight: 700;
  font-size: 0.85rem;
  margin-bottom: 10px;
  color: var(--ink);
}
.variant-options { display: flex; flex-wrap: wrap; gap: 8px; }
.variant-pill {
  position: relative;
}
.variant-pill input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.variant-pill span {
  display: inline-flex;
  align-items: center;
  padding: 9px 16px;
  border-radius: 999px;
  border: 1px solid var(--line);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
  background: var(--white);
}
.variant-pill input:checked + span {
  border-color: var(--piece-accent, var(--ink));
  color: var(--ink);
  background: var(--piece-wash, var(--paper-2));
}
.variant-pill input:focus-visible + span { outline: 3px solid var(--ink); outline-offset: 2px; }
.variant-swatch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px 7px 8px;
}
.variant-swatch .dot {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1px solid rgb(18 18 22 / 0.25);
  display: inline-block;
}

.product-ctas { display: flex; flex-direction: column; gap: 12px; margin: 22px 0; max-width: 420px; }
.checkout-pending {
  font-size: 0.78rem;
  color: var(--ink-soft);
  margin-top: -4px;
}

.trust-row { display: flex; flex-direction: column; gap: 8px; margin-top: 22px; }
.trust-row li {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-soft);
  font-size: 0.88rem;
}
.trust-row li svg { width: 15px; height: 15px; flex-shrink: 0; color: var(--ink-soft); }
.trust-row a { color: var(--piece-accent, var(--ink)); text-decoration: underline; text-underline-offset: 2px; }
.trust-row a:hover, .trust-row a:focus-visible { color: var(--ink); }

.product-signature { margin-top: 26px; }

/* More work strip */
.more-work { margin-top: 20px; }

/* ---- Colour story (signature move 3.4) ---------------------------------------------------------- */
.color-story { margin-top: 8px; }
.color-story h2 { font-size: 1.1rem; text-transform: none; letter-spacing: 0; margin-bottom: 16px; color: var(--ink); }
.swatch-row { display: flex; flex-wrap: wrap; gap: 14px; }
.swatch-chip { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 64px; }
.swatch-fill {
  width: 56px;
  height: 56px;
  border-radius: 8px;
  border: 1px solid var(--line);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.5);
}
.swatch-hex { font-size: 0.66rem; color: var(--ink-soft); }

/* ---- Reserve / inquiry form ---------------------------------------------------------------------- */
.reserve-form {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(20px, 4vw, 32px);
}
.reserve-form-wrap h2 { color: var(--ink); }
.form-row { margin-bottom: 18px; }
.form-row label {
  font-weight: 700;
  font-size: 0.86rem;
  margin-bottom: 8px;
  color: var(--ink);
}
.form-row .hint { color: var(--ink-soft); font-size: 0.78rem; margin-top: 6px; }
.form-row input[type="text"],
.form-row input[type="email"],
.form-row textarea {
  width: 100%;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
  padding: 12px 14px;
  font-size: 0.95rem;
}
.form-row input::placeholder, .form-row textarea::placeholder { color: #7A7A84; }
.form-row input:focus-visible, .form-row textarea:focus-visible {
  outline: 3px solid var(--piece-accent, var(--ink));
  outline-offset: 1px;
  border-color: var(--piece-accent, var(--ink));
}
.form-row textarea { min-height: 130px; resize: vertical; }
.form-row[data-invalid="true"] input,
.form-row[data-invalid="true"] textarea {
  border-color: #B3261E;
}
.form-error {
  color: #B3261E;
  font-size: 0.8rem;
  margin-top: 6px;
  display: none;
}
.form-row[data-invalid="true"] .form-error { display: block; }
.form-status {
  margin-top: 16px;
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  display: none;
}
.form-status.is-visible { display: block; }
.form-status.is-success { background: rgb(64 111 12 / 0.08); border: 1px solid rgb(64 111 12 / 0.3); color: #3E6B0C; }
.form-status.is-error { background: rgb(179 38 30 / 0.08); border: 1px solid rgb(179 38 30 / 0.3); color: #8C1F19; }
.form-status a { text-decoration: underline; font-weight: 700; color: inherit; }
.form-hidden-field { display: none; }

/* ---- Generic content pages -------------------------------------------------------------------------- */
.page-hero {
  padding-top: clamp(48px, 8vw, 84px);
  padding-bottom: clamp(16px, 3vw, 32px);
}
.page-hero .eyebrow { margin-bottom: 12px; }
.page-hero p.lede { margin-top: 16px; }

.steps-grid {
  display: grid;
  gap: 20px;
  grid-template-columns: 1fr;
}
@media (min-width: 700px) {
  .steps-grid { grid-template-columns: repeat(2, 1fr); }
}
.step-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
}
.step-card .n {
  font-family: var(--font-display);
  font-size: 2.2rem;
  color: var(--ink-soft);
  line-height: 1;
  margin-bottom: 10px;
}
.step-card h3 { margin-bottom: 8px; font-size: 1.15rem; text-transform: none; letter-spacing: 0; color: var(--ink); }
.step-card p { color: var(--ink-soft); font-size: 0.92rem; }

.about-sections { display: flex; flex-direction: column; gap: 28px; margin-top: 8px; }
.about-sections h3 { text-transform: none; letter-spacing: 0; font-size: 1.4rem; margin-bottom: 10px; color: var(--ink); }
.about-sections p { color: var(--ink-soft); }

.press-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
  margin-top: 28px;
}
.press-card .eyebrow { margin-bottom: 8px; }
.press-card a { color: var(--ink); font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.press-card a:hover, .press-card a:focus-visible { color: var(--ink-soft); }

.pull-quote {
  border-left: 4px solid var(--ink);
  padding-left: 20px;
  font-size: 1.3rem;
  line-height: 1.5;
  margin: 32px 0;
  color: var(--ink);
}
.pull-quote cite { display: block; margin-top: 12px; font-style: normal; font-size: 0.85rem; color: var(--ink-soft); }

.donation-list { display: flex; flex-direction: column; gap: 14px; margin-top: 18px; }
.donation-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 16px 18px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.donation-row .amount { font-family: var(--font-display); color: var(--ink); font-size: 1.3rem; }
.donation-row .meta { color: var(--ink-soft); font-size: 0.85rem; }
.donation-row .date { color: var(--ink-soft); font-size: 0.8rem; }

.policy-block { margin-bottom: 32px; }
.policy-block h2 { font-size: 1.4rem; text-transform: none; letter-spacing: 0; margin-bottom: 14px; color: var(--ink); }
.policy-block p { color: var(--ink-soft); margin-bottom: 10px; }

.contact-channels { display: flex; flex-direction: column; gap: 14px; margin-bottom: 32px; }
.contact-channel {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-weight: 600;
  color: var(--ink);
}
.contact-channel svg { width: 20px; height: 20px; color: var(--ink-soft); flex-shrink: 0; }

.two-col {
  display: grid;
  gap: 40px;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .two-col { grid-template-columns: 1fr 1fr; align-items: start; }
}

/* Contact page: links out to Commissions and Community, beside the channels. */
.contact-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }

/* A pull-quote given more weight than the standard .pull-quote: used for the
   radio-station quote on /community/ (the one genuine third-party proof in
   the whole harvest) and for the Voyage quote on /about/. */
.pull-quote-major {
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  border-left-width: 6px;
  line-height: 1.35;
  max-width: 44ch;
  margin: 0 auto;
}
.pull-quote-major cite { font-size: 0.92rem; margin-top: 16px; }

.strip-heading {
  font-size: 1.1rem;
  text-transform: none;
  letter-spacing: 0;
  margin-bottom: 20px;
  color: var(--ink);
}

/* ---- About page additions (v3: fixing the thin page) ------------------------------- */
.portrait-band {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  height: clamp(280px, 46vw, 560px);
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}
.portrait-band img { width: 100%; height: 100%; object-fit: cover; object-position: 60% 20%; }
.about-sections-grid {
  display: grid;
  gap: 28px;
  grid-template-columns: 1fr;
}
@media (min-width: 700px) {
  .about-sections-grid { grid-template-columns: repeat(2, 1fr); gap: 36px; }
}
.pull-quote-block { padding-block: clamp(56px, 9vw, 100px); text-align: center; }
.process-strip {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  padding-bottom: 6px;
  scrollbar-width: thin;
}
.process-strip-tile {
  flex: 0 0 auto;
  width: clamp(140px, 22vw, 220px);
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper-2);
}
.process-strip-tile img { width: 100%; height: 100%; object-fit: cover; }
.about-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* ---- Commissions page additions ----------------------------------------------------- */
.commission-row {
  display: grid;
  gap: 20px;
  grid-template-columns: 1fr;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
}
@media (min-width: 700px) {
  .commission-row { grid-template-columns: 240px 1fr; align-items: center; }
}
.commission-row-media { aspect-ratio: 3 / 4; border-radius: var(--radius-sm); overflow: hidden; background: var(--paper-2); }
.commission-row-media img { width: 100%; height: 100%; object-fit: cover; }
.commission-row-date { color: var(--ink-soft); font-size: 0.82rem; margin-bottom: 6px; }
.commission-row-body p:not(.commission-row-date) { color: var(--ink); margin-top: 6px; }
.commission-cta { text-align: center; padding-block: clamp(40px, 7vw, 72px); }
.commission-cta h2 { max-width: 22ch; margin-inline: auto; }
.two-col-faq-form { align-items: start; }
.faq-list h2 { margin-bottom: 20px; }
.faq-item { margin-bottom: 22px; padding-bottom: 22px; border-bottom: 1px solid var(--line); }
.faq-item:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }
.faq-item h3 { text-transform: none; letter-spacing: 0; font-size: 1.05rem; margin-bottom: 8px; color: var(--ink); }
.faq-item p { color: var(--ink-soft); font-size: 0.95rem; }

/* ---- Homepage community + gallery bands (v3 reorder) -------------------------------- */
.community-band, .gallery-band { padding-block: clamp(48px, 8vw, 88px); }
.gallery-band-grid {
  display: grid;
  gap: 32px;
  align-items: center;
}
@media (min-width: 780px) {
  .gallery-band-grid { grid-template-columns: 1fr auto; }
}
.gallery-band-strip { display: flex; gap: 10px; flex-wrap: wrap; }
.gallery-band-tile {
  /* display:block is load-bearing, same as .salon-frame: this is a <span>,
     and width/height are ignored on non-replaced inline elements. */
  display: block;
  width: 92px;
  height: 92px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--white);
  flex: 0 0 auto;
}
.gallery-band-tile picture, .gallery-band-tile img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* ---- /community/ ---------------------------------------------------------------------
   The proof page (REDESIGN-SPEC-V3.md section 3). Hero is the one vivid block
   on this page; everything below alternates paper and paper-2. */
.community-hero { padding-block: clamp(64px, 11vw, 120px); text-align: center; }
.community-hero .wrap { max-width: 720px; }
.community-hero .lede { color: inherit; opacity: 0.92; max-width: 52ch; margin-inline: auto; }
.community-total {
  font-family: var(--font-display);
  font-size: clamp(3.6rem, 13vw, 7rem);
  line-height: 0.92;
  margin-top: 28px;
}
.community-total-label { font-size: 1.05rem; margin-top: 8px; font-weight: 600; }
.community-total-qualifier { font-size: 0.82rem; opacity: 0.78; margin-top: 4px; }

.giving-list, .timeline-list { display: flex; flex-direction: column; gap: 20px; margin-top: 24px; }
.giving-row, .timeline-row {
  display: grid;
  gap: 18px;
  grid-template-columns: 1fr;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
}
@media (min-width: 700px) {
  /* These photos are the proof: a donation cheque being handed over, a piece in
     someone's hands at a named venue. At 180px to 220px they were thumbnails
     next to a paragraph. Give them roughly half the row and let the text sit
     beside them. */
  .giving-row { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr); }
  .timeline-row { grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr); }
}
@media (min-width: 1000px) {
  .giving-row, .timeline-row { gap: 28px; padding: 24px; align-items: center; }
}
.giving-row-media, .timeline-row-media {
  display: block;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--paper-2);
  /* Landscape, because every one of these is a group shot or a cheque being
     handed over. A 4:5 portrait crop sliced the people out of the sides. */
  aspect-ratio: 4 / 3;
}
.giving-row-media img, .timeline-row-media img { width: 100%; height: 100%; object-fit: cover; }
.giving-row-date, .timeline-row-date { color: var(--ink-soft); font-size: 0.82rem; margin-bottom: 6px; }
.giving-row-body h3 { text-transform: none; letter-spacing: 0; font-size: 1.2rem; margin-bottom: 6px; color: var(--ink); }
.giving-row-amount { font-family: var(--font-display); font-size: 1.5rem; color: var(--ink); margin-bottom: 4px; }
.giving-row-location { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 8px; }
.giving-row-body p:not([class]) { color: var(--ink-soft); margin-top: 6px; }
.giving-row-quote { margin: 14px 0 0; border-left-width: 3px; font-size: 1rem; }
.timeline-row-kind { font-weight: 700; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-soft); margin-bottom: 6px; }
.timeline-row-body p:not([class]) { color: var(--ink); margin-top: 4px; }

.radio-quote-section { text-align: center; }

.cause-card-row { display: flex; flex-wrap: wrap; gap: 16px; margin: 22px 0; }
.cause-card {
  display: flex;
  flex-direction: column;
  width: 180px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--white);
  transition: border-color .3s ease, transform .3s cubic-bezier(.32,.72,0,1);
}
.cause-card:hover, .cause-card:focus-visible { border-color: var(--piece-accent, var(--ink)); transform: translateY(-4px); }
@media (prefers-reduced-motion: reduce) {
  .cause-card:hover, .cause-card:focus-visible { transform: none; }
}
/* display:block is load-bearing here too (see the .salon-frame comment
   above): .cause-card-media is a <span>, and aspect-ratio is ignored on
   non-replaced inline elements. */
.cause-card-media { display: block; aspect-ratio: 1; background: var(--paper-2); }
.cause-card-media img { width: 100%; height: 100%; object-fit: cover; }
.cause-card-title { display: block; padding: 12px 14px; font-weight: 700; font-size: 0.88rem; color: var(--ink); }

.sourcing-note { color: var(--ink-soft); font-size: 0.82rem; border-top: 1px solid var(--line); padding-top: 20px; }

/* ---- /gallery/ ------------------------------------------------------------------------
   Album index cards plus the dense per-album grid. See section 4 of the spec:
   real aspect, no library, product items skip the lightbox. */
.album-grid {
  display: grid;
  gap: 20px;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .album-grid { grid-template-columns: repeat(2, 1fr); }
}
.album-card {
  display: block;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform .3s cubic-bezier(.32,.72,0,1), box-shadow .3s ease;
}
.album-card:hover, .album-card:focus-visible { transform: translateY(-4px); box-shadow: var(--shadow-lift); }
@media (prefers-reduced-motion: reduce) {
  .album-card:hover, .album-card:focus-visible { transform: none; }
}
/* display:block is load-bearing here too: .album-card-media is a <span>,
   and aspect-ratio is ignored on non-replaced inline elements. */
.album-card-media { display: block; aspect-ratio: 4 / 3; background: var(--paper-2); }
.album-card-media img { width: 100%; height: 100%; object-fit: cover; }
.album-card-body { display: block; padding: 18px 20px 22px; }
.album-card-title { display: block; font-family: var(--font-display); text-transform: uppercase; font-size: 1.3rem; color: var(--ink); }
.album-card-blurb { display: block; color: var(--ink-soft); font-size: 0.9rem; margin-top: 8px; }
.album-card-count { display: block; color: var(--ink-soft); font-size: 0.78rem; margin-top: 10px; }

/* CSS-columns masonry: honours each photo's real intrinsic aspect (via the
   width/height attributes build.mjs writes on every <img>) instead of
   cropping to a uniform tile. This is deliberately not aspect-ratio boxes:
   items are <a> elements with natural height, so the "aspect-ratio is
   ignored on inline elements" trap that hit .salon-frame never applies here. */
.gallery-masonry {
  column-count: 2;
  column-gap: 12px;
}
@media (min-width: 560px) { .gallery-masonry { column-count: 3; } }
@media (min-width: 900px) { .gallery-masonry { column-count: 4; } }
.gallery-item {
  display: block;
  break-inside: avoid;
  margin-bottom: 12px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--white);
  position: relative;
  transition: transform .3s cubic-bezier(.32,.72,0,1), border-color .3s ease;
}
.gallery-item:hover, .gallery-item:focus-visible { transform: translateY(-3px); border-color: var(--piece-accent, var(--ink-soft)); }
@media (prefers-reduced-motion: reduce) {
  .gallery-item:hover, .gallery-item:focus-visible { transform: none; }
}
.gallery-item-media img { width: 100%; height: auto; display: block; }
.gallery-item-caption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  font-size: 0.78rem;
  color: var(--ink-soft);
}
.gallery-item-product .gallery-item-caption { flex-direction: column; align-items: flex-start; gap: 4px; }
.gallery-item-product .t { font-weight: 700; color: var(--ink); font-size: 0.85rem; }
.gallery-item-product .p { color: var(--piece-accent, var(--ink)); font-weight: 700; }
.gallery-item-caption-photo .t { color: var(--ink-soft); }

/* ---- Hand-rolled lightbox --------------------------------------------------------------
   No library. Focus trap, Escape, arrow keys, aria-modal, named close button,
   and caption/date/location/source link are all wired in site.js. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 900;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(12px, 4vw, 40px);
}
.lightbox[hidden] { display: none; }
.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgb(10 10 12 / 0.92);
}
.lightbox-dialog {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1000px;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  background: #0B0B0D;
  border-radius: var(--radius);
  overflow: hidden;
  opacity: 0;
  transform: scale(0.97);
  transition: opacity .22s ease, transform .22s ease;
}
.lightbox.is-open .lightbox-dialog { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .lightbox-dialog { transition: none; }
}
html.a11y-reduce-motion .lightbox-dialog { transition: none; }
.lightbox-media {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  padding: 12px;
}
.lightbox-media picture { display: block; width: 100%; height: 100%; }
.lightbox-media img { width: 100%; height: 100%; object-fit: contain; display: block; }
.lightbox-info {
  flex: 0 0 auto;
  padding: 16px 20px 20px;
  color: #EDEDF0;
  background: #0B0B0D;
  border-top: 1px solid rgb(255 255 255 / 0.12);
}
.lightbox-caption { font-size: 0.95rem; color: #EDEDF0; max-width: 70ch; }
.lightbox-meta { color: #A9A9B4; font-size: 0.82rem; margin-top: 6px; }
.lightbox-source {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--lime);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.lightbox-source svg { width: 13px; height: 13px; }
.lightbox-source:hover, .lightbox-source:focus-visible { color: #fff; }
.lightbox-btn {
  position: absolute;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgb(11 11 13 / 0.75);
  color: #fff;
  border: 1px solid rgb(255 255 255 / 0.25);
}
.lightbox-btn:hover, .lightbox-btn:focus-visible { background: rgb(11 11 13 / 0.95); border-color: rgb(255 255 255 / 0.6); }
.lightbox-btn svg { width: 20px; height: 20px; }
.lightbox-close { top: 12px; right: 12px; }
.lightbox-prev { left: 12px; top: 50%; transform: translateY(-50%); }
.lightbox-next { right: 12px; top: 50%; transform: translateY(-50%); }
.lightbox-btn[hidden] { display: none; }
@media (max-width: 640px) {
  .lightbox-dialog { max-height: 92vh; }
  .lightbox-media { padding: 6px; }
}

/* ---- 404 ------------------------------------------------------------------------------------------------ */
.not-found {
  min-height: 70vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 60px var(--gutter);
}
.not-found-inner { max-width: 480px; }
.not-found img { width: 160px; margin: 0 auto 28px; }
.not-found .btn { margin-top: 22px; }

/* ---- Cookie consent banner ---------------------------------------------------------------------------------- */
.consent-banner {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 800;
  background: var(--white);
  border-top: 1px solid var(--line);
  box-shadow: 0 -12px 30px rgb(18 18 22 / 0.12);
  padding: 18px var(--gutter);
  display: none;
}
.consent-banner.is-visible { display: block; }
.consent-inner {
  max-width: var(--container);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
@media (min-width: 700px) {
  .consent-inner { flex-direction: row; align-items: center; justify-content: space-between; gap: 24px; }
}
.consent-text { font-size: 0.85rem; color: var(--ink-soft); max-width: 60ch; }
.consent-text strong { color: var(--ink); }
.consent-actions { display: flex; gap: 10px; flex-shrink: 0; flex-wrap: wrap; }
.consent-actions .btn { padding: 10px 20px; font-size: 0.85rem; }
/* Explicit background so a real, visible, equally-weighted alternative sits
   next to Accept. A dark fill on a white banner is unmistakably a button,
   which is the direct fix for the fleet's recurring invisible-decline bug. */
.btn-decline {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}
.btn-decline:hover, .btn-decline:focus-visible { background: #2A2A30; border-color: #2A2A30; }

/* ---- Accessibility widget --------------------------------------------------------------------------------------- */
.a11y-toggle {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 700;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--orange);
  color: #150900;
  border: 2px solid #150900;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-lift);
}
.a11y-toggle svg { width: 22px; height: 22px; }
.a11y-toggle:hover, .a11y-toggle:focus-visible { background: #ff8c1f; }

.a11y-panel {
  position: fixed;
  right: 16px;
  bottom: 76px;
  z-index: 700;
  width: min(280px, calc(100vw - 32px));
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
  box-shadow: var(--shadow-lift);
  display: none;
}
.a11y-panel.is-open { display: block; }
.a11y-panel h2 { font-size: 1rem; text-transform: none; letter-spacing: 0; margin-bottom: 14px; color: var(--ink); }
.a11y-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
.a11y-row:last-of-type { border-bottom: none; }
.a11y-row span { font-size: 0.88rem; color: var(--ink); }
.a11y-switch {
  position: relative;
  width: 42px;
  height: 24px;
  border-radius: 999px;
  background: var(--line);
  border: none;
  cursor: pointer;
  flex-shrink: 0;
}
.a11y-switch::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--white);
  box-shadow: 0 1px 3px rgb(18 18 22 / 0.3);
  transition: transform .2s ease;
}
.a11y-switch[aria-pressed="true"] { background: var(--orange); }
.a11y-switch[aria-pressed="true"]::after { transform: translateX(18px); background: #150900; }
.a11y-reset {
  width: 100%;
  margin-top: 14px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 9px;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  color: var(--ink);
}
.a11y-reset:hover, .a11y-reset:focus-visible { border-color: var(--ink-soft); }

/* Accessibility states applied to <html>. Contrast mode is implemented as a
   token remap (paper to pure white, ink to pure black, hairlines to black)
   rather than a filter hack, so text stays legible and the knockout fallback
   above actually takes over instead of fighting a CSS filter. */
html.a11y-contrast {
  --paper: #FFFFFF;
  --paper-2: #FFFFFF;
  --ink: #000000;
  --ink-soft: #222226;
  --line: #000000;
}
html.a11y-contrast body { background: #FFFFFF; }
html.a11y-text-lg { font-size: 112.5%; }
html.a11y-reduce-motion.js .fade-up,
html.a11y-reduce-motion .fade-up { opacity: 1 !important; transform: none !important; }
html.a11y-reduce-motion * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }

/* ---- Utility ---------------------------------------------------------------------------------------------------- */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* ---- Product specs (the <ul> Wix kept separate from the prose) ------------ */
.product-specs {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  display: grid;
  gap: 8px;
}
.product-specs li {
  position: relative;
  padding-left: 16px;
  font-size: 0.92rem;
  color: var(--ink-soft);
  max-width: 60ch;
}
.product-specs li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--piece-accent, var(--ink-soft));
}

/* ---- Contact: "what you can ask me" panel -------------------------------
   The contact page ended right after a short form, leaving a tall empty run
   above the footer. This panel gives the left column real substance and tells
   people what is actually worth writing in about. */
.contact-what { margin-top: 34px; padding-top: 26px; border-top: 1px solid var(--line); }
.contact-what-heading {
  font-size: 1.1rem;
  text-transform: none;
  letter-spacing: 0;
  margin-bottom: 16px;
}
.contact-what-list { display: grid; gap: 16px; }
.contact-what-list li {
  display: grid;
  gap: 3px;
  padding-left: 16px;
  position: relative;
  max-width: 46ch;
}
.contact-what-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--piece-accent, var(--orange));
}
.contact-what-list .t { font-weight: 700; color: var(--ink); }
.contact-what-list .b { color: var(--ink-soft); font-size: 0.94rem; }
