/* ==========================================================================
   GB Custom Leather Craft — base stylesheet
   Mobile-first. Breakpoints: 480, 768, 1024, 1440
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--color-background);
  color: var(--color-text);
  font-family: var(--font-body-family);
  font-style: var(--font-body-style);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-heading-family);
  font-style: var(--font-heading-style);
  color: var(--color-heading);
  line-height: 1.15;
  margin: 0;
}

p { margin: 0 0 1em; }
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }

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

.skip-to-content {
  position: absolute;
  top: -100px;
  left: 1rem;
  z-index: 1000;
  background: var(--color-leather-dark);
  color: #fff;
  padding: 0.75em 1.25em;
  border-radius: 4px;
  transition: top 0.15s ease;
}
.skip-to-content:focus { top: 1rem; }

/* 2.3.3 / vestibular safety. The hero video already refuses to play under
   prefers-reduced-motion and the configurator stills its own transitions, but
   base.css had five transitions of its own — two of them transforms, the tile
   zoom and the card lift — plus smooth scrolling on <html>, and none of them
   asked. A person who has told their operating system that motion makes them
   ill should not have to ask the website twice. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* THE ONE GLOBAL FOCUS RING, AND IT HAD THREE IMPOSTORS.
   A find-and-replace once spliced the reduced-motion comment and its media
   query into the middle of three selector lists — `.btn--primary:hover,
   .btn--primary` + <the block> + `:focus-visible` — which left the browser
   parsing a bare, unscoped `:focus-visible` three more times. Measured by
   pressing Tab twelve times on the configurator: an ordinary footer link
   with no class reached `transform: matrix(1.06, 0, 0, 1.06, 0, -2)`,
   `background: rgb(26, 19, 14)` and `color: rgb(246, 241, 233)` — the
   social icon's lift-and-scale and the secondary button's color inversion,
   on a line of text. Every keyboard user on every page saw it. The same
   splice also took `.btn--primary:hover` and `.btn--secondary:hover` out of
   the stylesheet entirely, so the site's main call to action had no hover
   state at all, and it left four copies of the reduced-motion block.
   Repaired to the three scoped rules it was written as; this is the only
   unscoped one. */
:focus-visible {
  outline: 3px solid var(--color-brass);
  outline-offset: 2px;
}

/* THE RING, WHEN THE PAGE MOVED THE FOCUS ITSELF.
   Every focus indicator here is :focus-visible only, which is right for a
   mouse click on a button — and wrong when Continue sends somebody to the
   question they missed. The browser does not consider a programmatic focus
   after a click "visible", so the customer was scrolled to a field with no
   mark on it at all and left to guess which one was meant.

   gb-commission.js sets data-focus-forced for as long as that field holds
   focus. The option radios are opacity:0 overlays, so the ring is drawn on
   the box a person can actually see. */
[data-focus-forced] {
  outline: 3px solid var(--color-brass);
  outline-offset: 2px;
}
[data-focus-forced].cmsn-opt__input,
[data-focus-forced][type="radio"],
[data-focus-forced][type="checkbox"] {
  outline: none;
}
label:has([data-focus-forced]) .cmsn-opt__box {
  outline: 3px solid var(--color-brass);
  outline-offset: 2px;
}

.container {
  width: 100%;
  max-width: var(--page-width, 1280px);
  margin: 0 auto;
  padding: 0 1.25rem;
}

@media (min-width: 768px) {
  .container { padding: 0 2rem; }
}

/* ---------------------------------------------------------------- Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0.85em 1.75em;
  border-radius: 2px;
  font-family: var(--font-body-family);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
  border: 2px solid transparent;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.btn--primary {
  background: var(--color-leather);
  color: var(--color-button-text);
  border-color: var(--color-leather);
}
.btn--primary:hover, .btn--primary:focus-visible { background: var(--color-leather-dark); border-color: var(--color-leather-dark); }

.btn--secondary {
  background: transparent;
  color: var(--color-heading);
  border-color: var(--color-heading);
}
.btn--secondary:hover, .btn--secondary:focus-visible { background: var(--color-heading); color: var(--color-background); }

.btn--large { min-height: 54px; padding: 1em 2.25em; font-size: 1rem; }

/* ------------------------------------------------------------------ Header */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--color-background);
  border-bottom: 1px solid rgba(0,0,0,0.08);
}

/* HALF THE HEIGHT, SAME HEADER.
   It stood at 205px on a 1280-wide screen — the logo alone was 178px of that,
   with the padding making up the rest — which is a quarter of a laptop screen
   spent before the page begins. Both are halved and nothing else changes: same
   logo, same navigation, same call to action, same order. */
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 0.425rem;
  padding-bottom: 0.425rem;
}

.site-header__logo { display: inline-flex; align-items: center; }
.site-header__logo-image { width: 80px; height: auto; }
.site-header__logo-placeholder {
  display: inline-block;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-leather);
  border: 1px dashed var(--color-leather);
  padding: 0.5em 0.75em;
  max-width: 160px;
}

.site-header__nav { display: none; }
.site-header__nav-list { display: flex; gap: 1.75rem; }
.site-header__nav-link {
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 0.5em 0;
  border-bottom: 2px solid transparent;
}
.site-header__nav-link:hover,
.site-header__nav-link[aria-current="page"] { border-bottom-color: var(--color-leather); }

.site-header__actions { display: flex; align-items: center; gap: 0.75rem; }
.site-header__cta { display: none; }

.site-header__menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: transparent;
  border: none;
  cursor: pointer;
}
.site-header__menu-icon,
.site-header__menu-icon::before,
.site-header__menu-icon::after {
  display: block;
  width: 24px;
  height: 2px;
  background: var(--color-heading);
  position: relative;
  transition: transform 0.15s ease, opacity 0.15s ease;
}
.site-header__menu-icon::before, .site-header__menu-icon::after { content: ""; position: absolute; left: 0; }
.site-header__menu-icon::before { top: -7px; }
.site-header__menu-icon::after { top: 7px; }

.site-header__menu-toggle[aria-expanded="true"] .site-header__menu-icon { background: transparent; }
.site-header__menu-toggle[aria-expanded="true"] .site-header__menu-icon::before { top: 0; transform: rotate(45deg); }
.site-header__menu-toggle[aria-expanded="true"] .site-header__menu-icon::after { top: 0; transform: rotate(-45deg); }

.mobile-nav {
  border-bottom: 1px solid rgba(0,0,0,0.08);
  background: var(--color-background);
}
.mobile-nav[hidden] { display: none; }
.mobile-nav__list { padding: 0.5rem 1.25rem 1.25rem; }
.mobile-nav__link {
  display: block;
  padding: 0.85em 0;
  font-size: 1.05rem;
  font-weight: 600;
  border-bottom: 1px solid rgba(0,0,0,0.06);
}
.mobile-nav__item--cta { padding-top: 1rem; }
.mobile-nav__cta { width: 100%; }

@media (min-width: 1024px) {
  .site-header__nav { display: block; }
  .site-header__cta { display: inline-flex; }
  .site-header__menu-toggle { display: none; }
  .mobile-nav { display: none !important; }
}

/* -------------------------------------------------------------------- Hero */
.hero { position: relative; min-height: 88vh; display: flex; align-items: flex-end; overflow: hidden; }
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__image { width: 100%; height: 100%; object-fit: cover; }
.hero__placeholder {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-leather-dark);
  color: #fff;
  text-align: center;
  padding: 2rem;
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
/* THE SCRIM IS A CONTRAST CONTROL, NOT A MOOD.
   White text over a photograph only meets WCAG 1.4.3 where the pixels behind
   the glyphs are dark enough. Measured against the real hero poster by
   compositing this gradient and sampling every pixel under the heading box:
   at 0.15 -> 0.65 the worst contrast was 2.10:1 where the headline needs 3:1,
   and 3.66:1 where the sub-heading needs 4.5:1 — a small bright region, but a
   real failure. At 0.35 -> 0.70 nothing in either box falls below its
   threshold, worst 3.42:1 and 5.36:1. Do not lighten these without
   re-measuring. */
.hero__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.35) 0%, rgba(0,0,0,.70) 100%);
}
.hero__content { position: relative; z-index: 1; color: #fff; padding-bottom: 3.5rem; padding-top: 6rem; }
.hero__headline {
  font-size: clamp(2.1rem, 8vw, 4.5rem);
  white-space: pre-line;
  margin-bottom: 0.5em;
  text-shadow: 0 2px 12px rgba(0,0,0,0.35);
}
.hero__subhead {
  max-width: 40ch;
  font-size: 1.05rem;
  margin-bottom: 1.5em;
  text-shadow: 0 1px 6px rgba(0,0,0,0.35);
}
.hero__actions { display: flex; flex-direction: column; gap: 0.85rem; max-width: 320px; }

@media (min-width: 768px) {
  .hero { min-height: 92vh; }
  .hero__actions { flex-direction: row; max-width: none; }
}

/* --------------------------------------------------------- Section shared */
section { padding: 4rem 0; }

.section-heading { max-width: 46rem; margin: 0 auto 2.5rem; text-align: center; }
.section-heading__title {
  font-size: clamp(1.6rem, 4.5vw, 2.5rem);
  white-space: pre-line;
}
.section-heading__subhead { margin-top: 0.75em; font-size: 1.05rem; color: var(--color-text); opacity: 0.85; }

@media (min-width: 768px) {
  section { padding: 6rem 0; }
}

/* -------------------------------------------------------------- Difference */
.difference { background: var(--color-surface); }
.difference__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}
.difference__card {
  padding: 2rem 1.5rem;
  border: 1px solid rgba(0,0,0,0.08);
  border-radius: 4px;
  text-align: center;
}
.difference__card-title { font-size: 1.15rem; margin-bottom: 0.5em; }
.difference__card-text { margin: 0; opacity: 0.85; }

@media (min-width: 640px) {
  .difference__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .difference__grid { grid-template-columns: repeat(4, 1fr); }
}

/* ------------------------------------------------------------- Commissions */
.commissions__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}
.commissions__link { display: block; }
.commissions__image-wrap {
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--color-leather-dark);
  border-radius: 4px;
}
.commissions__image { width: 100%; height: 100%; object-fit: cover; transition: transform 0.3s ease; }
.commissions__link:hover .commissions__image { transform: scale(1.04); }
.commissions__placeholder {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%;
  color: #fff; text-align: center; padding: 1.5rem;
  font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.03em;
}
.commissions__caption { display: block; padding-top: 0.85rem; }
/* A <figure> carries a default margin that an <a> does not, and this class is
   used as both. The six on the past commissions page each cancel it with an
   inline style; stating it once here meant the guitar strap page did not have
   to add a seventh — the build pins the number of inline styles precisely so
   that copying a pattern cannot quietly raise it. */
figure.commissions__link { margin: 0; }
.commissions__category {
  display: inline-block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-leather);
  margin-bottom: 0.35em;
}
.commissions__title { display: block; font-family: var(--font-heading-family); font-size: 1.1rem; }
.commissions__description { display: block; font-size: 0.9rem; opacity: 0.8; margin-top: 0.25em; }
.commissions__footer { text-align: center; margin-top: 2.5rem; }

@media (min-width: 640px) {
  .commissions__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .commissions__grid { grid-template-columns: repeat(3, 1fr); }
}

/* ----------------------------------------------------------------- Process */
.process { background: var(--color-leather-dark); color: #fff; }
.process .section-heading__title,
.process .section-heading__subhead { color: #fff; }
.process__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  counter-reset: step;
}
.process__step { text-align: center; }
.process__number {
  display: inline-block;
  font-family: var(--font-heading-family);
  font-size: 1.1rem;
  color: var(--color-brass);
  margin-bottom: 0.5em;
}
.process__title { font-size: 1.2rem; margin-bottom: 0.4em; color: #fff; }
.process__text { opacity: 0.85; margin: 0; max-width: 28ch; margin-inline: auto; }
.process__footer { text-align: center; margin-top: 3rem; }

@media (min-width: 640px) {
  .process__list { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .process__list { grid-template-columns: repeat(4, 1fr); }
}

/* ---------------------------------------------------------------- Artisan */
.artisan__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  align-items: center;
}
.artisan__media { border-radius: 4px; overflow: hidden; }
.artisan__image { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4 / 5; }
.artisan__placeholder {
  aspect-ratio: 4 / 5;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-surface);
  border: 1px dashed var(--color-leather);
  text-align: center;
  padding: 2rem;
  color: var(--color-leather);
  text-transform: uppercase;
  font-size: 0.85rem;
  letter-spacing: 0.03em;
}
.artisan__heading { font-size: clamp(1.5rem, 4vw, 2.1rem); margin-bottom: 0.6em; }
.artisan__text { margin-bottom: 1.5em; opacity: 0.9; }

@media (min-width: 768px) {
  .artisan__inner { grid-template-columns: 1fr 1fr; }
}

/* --------------------------------------------------------------- Final CTA */
.final-cta { background: var(--color-heading); color: #fff; text-align: center; }
.final-cta__headline { font-size: clamp(1.8rem, 5vw, 2.75rem); margin-bottom: 0.5em; }
.final-cta__subhead { opacity: 0.85; margin-bottom: 1.75em; }

/* ---------------------------------------------------------------- Footer */
.site-footer { background: var(--color-surface); border-top: 1px solid rgba(0,0,0,0.08); padding-top: 3.5rem; }
.site-footer__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  padding-bottom: 2.5rem;
}
.site-footer__logo img { width: 140px; }
.site-footer__logo-placeholder {
  display: inline-block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-leather);
  border: 1px dashed var(--color-leather);
  padding: 0.5em 0.75em;
}
.site-footer__tagline { margin-top: 0.75em; opacity: 0.75; font-style: italic; }
.site-footer__heading {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 1em;
  color: var(--color-heading);
}
.site-footer__nav-list li,
.site-footer__contact-list li { margin-bottom: 0.6em; opacity: 0.85; }

/* A FOOTER LINK IS A TARGET A THUMB HAS TO HIT.
   Measured at 375x812 on every public page: eleven to thirteen links in the
   footer, each an inline anchor 21px tall with no padding, under the 24px
   minimum target size — and they are the links a reader falls back on when
   the header's menu is closed. Made block-level with vertical padding so the
   target is the row rather than the glyphs, which also widens the hit area
   to the full column. The negative margin keeps the first row flush with the
   heading above it, so nothing moves visually. */
.site-footer__nav-list a,
.site-footer__contact-list a {
  display: block;
  padding: 0.35rem 0;
  min-height: 24px;
}
.site-footer__nav-list li,
.site-footer__contact-list li { margin-bottom: 0.1em; }
.site-footer__nav-list, .site-footer__contact-list { margin-top: -0.35rem; }
.site-footer__contact-list a { opacity: 1; }

.site-footer__social {
  padding: 0.5rem 0 2rem;
  border-top: 1px solid rgba(0,0,0,0.06);
  margin-top: 0.5rem;
}
.site-footer__social .site-footer__heading { margin-bottom: 1rem; opacity: 0.75; }

.social-icons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
}

.social-icon {
  --icon-brand: var(--color-leather);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(0,0,0,0.1);
  background: #fff;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.social-icon svg { width: 24px; height: 24px; display: block; }
.social-icon:hover,
.social-icon:focus-visible {
  border-color: var(--icon-brand);
  box-shadow: 0 4px 14px -2px color-mix(in srgb, var(--icon-brand) 55%, transparent);
  transform: translateY(-2px) scale(1.06);
}

.site-footer__bottom {
  border-top: 1px solid rgba(0,0,0,0.08);
  padding: 1.25rem 0;
  font-size: 0.8rem;
  opacity: 0.65;
}

@media (min-width: 768px) {
  .site-footer__inner { grid-template-columns: 1.5fr 1fr 1fr; }
}

@media (min-width: 1024px) {
  .social-icon { width: 40px; height: 40px; }
}

/* ------------------------------------------------------------- Basic pages */
.basic-page { padding: 5rem 0; }
.basic-page__title { font-size: clamp(1.8rem, 5vw, 2.5rem); margin-bottom: 1em; }
.basic-page__inner--centered { text-align: center; }
.rte p { margin-bottom: 1.2em; }

/* ----------------------------------------------- A page that explains money
   Built for /pages/what-it-costs, in the theme's own tokens rather than a
   second visual language. A table because the figures ARE a table: a
   customer comparing "what is the base" against "what does length add"
   should not have to read a paragraph twice. */
.lede { font-size: 1.15rem; line-height: 1.6; max-width: 46rem; margin-bottom: 2.5rem; }
.basic-page h2 { font-size: clamp(1.25rem, 3.2vw, 1.6rem); margin: 2.5rem 0 0.8em; }
.basic-page p { max-width: 46rem; line-height: 1.65; margin-bottom: 1.1em; }

.price-table { width: 100%; border-collapse: collapse; margin: 0 0 1.5rem; }
.price-table__caption { text-align: left; font-size: 0.95rem; opacity: 0.75;
  padding-bottom: 0.6em; }
.price-table th, .price-table td { text-align: left; vertical-align: baseline;
  padding: 0.9em 0.8em 0.9em 0; border-bottom: 1px solid rgba(0,0,0,0.1);
  line-height: 1.5; }
.price-table th { font-weight: 600; width: 34%; }
.price-table__amount { font-variant-numeric: tabular-nums; white-space: nowrap;
  font-weight: 600; color: var(--color-leather-dark, inherit); width: 18%; }

/* ON A PHONE A THREE-COLUMN TABLE IS UNREADABLE, so each row becomes a
   block: what it is, what it costs, what it means. No horizontal scroll. */
@media (max-width: 640px) {
  .price-table, .price-table tbody, .price-table tr, .price-table th,
  .price-table td { display: block; width: auto; }
  .price-table tr { padding: 1em 0; border-bottom: 1px solid rgba(0,0,0,0.1); }
  .price-table th, .price-table td { border: 0; padding: 0 0 0.3em; }
  .price-table__amount { font-size: 1.15rem; }
}

.price-note { font-size: 0.95rem; opacity: 0.8; border-left: 3px solid var(--color-brass, #b8893b);
  padding-left: 1em; margin-bottom: 2rem; }

.process-list { max-width: 46rem; line-height: 1.6; padding-left: 1.2em; }
.process-list li { margin-bottom: 0.9em; }

.faq { max-width: 46rem; }
.faq dt { font-weight: 600; margin-top: 1.4em; }
.faq dd { margin: 0.4em 0 0; line-height: 1.6; }

.cta-row { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-top: 2.5rem; }

/* ------------------------------------------------------- Cart / product misc */
.product__inner { display: grid; grid-template-columns: 1fr; gap: 2rem; padding: 3rem 0; }
.product__price { font-size: 1.25rem; margin-bottom: 1em; }
@media (min-width: 768px) { .product__inner { grid-template-columns: 1fr 1fr; } }

.cart-table { width: 100%; border-collapse: collapse; margin-bottom: 1.5rem; }
.cart-table th, .cart-table td { text-align: left; padding: 0.75em 0.5em; border-bottom: 1px solid rgba(0,0,0,0.08); }
.cart-table__total { font-size: 1.1rem; margin-bottom: 1em; }

.search-form { display: flex; gap: 0.75rem; margin: 1.5rem 0; max-width: 420px; }
.search-form__input { flex: 1; padding: 0.75em; border: 1px solid rgba(0,0,0,0.2); border-radius: 2px; }

/* ------------------------------------------------- Past Work: a record, and
   the honest absence of one
   /past-work and its item pages are GENERATED by scripts/build-site.mjs from
   theme/content/portfolio.json, and they shipped with no stylesheet at all:
   not one pw__ class below existed, so every rule the built markup asked for
   resolved to nothing. The empty state was two unstyled paragraphs, and the
   gallery — the half of the page nobody could see, because the record is
   empty — would have rendered as a single column of full-width photographs
   with each caption run into the next picture. Written here in the theme's own
   tokens and deliberately beside .commissions__* above: that section is the
   same gallery written by hand, and the two must not look like two different
   websites. */
.pw__grid { display: grid; grid-template-columns: 1fr; gap: 1.5rem; }
.pw__link { display: block; }
.pw__frame {
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--color-leather-dark);
  border-radius: 4px;
}
.pw__frame .pw__image { width: 100%; height: 100%; object-fit: cover; transition: transform 0.3s ease; }
.pw__link:hover .pw__frame .pw__image { transform: scale(1.04); }
.pw__meta { display: block; padding-top: 0.85rem; }
.pw__title { display: block; font-family: var(--font-heading-family); font-size: 1.1rem; color: var(--color-heading); }
.pw__type {
  display: block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-leather);
  margin-top: 0.35em;
}

@media (min-width: 640px) {
  .pw__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .pw__grid { grid-template-columns: repeat(3, 1fr); }
}

/* An item page shows its pictures whole rather than cropped to a tile. The
   belt photographs are 640x800 portraits and the tooling is the entire point
   of looking; the 4/5 tile above is for scanning a gallery, not for reading a
   piece of work.
   40rem, not the 46rem of the prose: 40rem is 640px, which is the width of
   the six belt and strap photographs in theme/content/media.json — the ones
   a portfolio item would actually use — so a portrait belt photograph fills
   its column on a wide screen without being scaled up past the pixels that
   exist. The other two cataloged images are not belt photographs and are
   not this size (the craftsman portrait is 496x661 and the hero poster is
   1600x900); an earlier version of this comment said "every photograph",
   which was two-eighths wrong and implied a guarantee nothing enforces. The
   build checks that a portfolio image EXISTS and is cataloged; it does not
   check its width, so a narrower one would be scaled up. The `sizes`
   attribute the build writes for this view states the same widths. */
.pw__crumb { font-size: 0.85rem; margin-bottom: 1.5em; }
.pw__crumb a { color: var(--color-leather); text-decoration: underline; text-underline-offset: 2px; }
.pw__gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  margin: 1.5rem 0 2rem;
  max-width: 40rem;
}
.pw__gallery .pw__image { width: 100%; height: auto; border-radius: 4px; }
.pw__story { max-width: 46rem; }

@media (min-width: 768px) {
  .pw__gallery { grid-template-columns: repeat(2, 1fr); }
}

/* THE EMPTY STATE IS A DESTINATION, NOT AN APOLOGY, so it is laid out like one
   of the written pages: the same 46rem measure as .lede and .basic-page p, and
   the same .cta-row at the bottom as /pages/what-it-costs. The list of routes
   is a list of rows rather than buttons, because four buttons of equal weight
   is four ways of saying nothing. */
.pw__empty { max-width: 46rem; }
.pw__next { margin: 0 0 1rem; }
.pw__next li { padding: 0.9em 0; border-bottom: 1px solid rgba(0,0,0,0.1); }
/* The signpost's title is the link, and an inline anchor of text is a 21px
   target — under the 24px minimum, measured at 375x812 on this page after
   the rest of the site's footer links had been widened. Made block-level so
   the target is the whole row rather than the few words in it. */
.pw__next a {
  display: block;
  padding: 0.15rem 0;
  min-height: 24px;
  font-weight: 600;
  color: var(--color-leather);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.pw__next span { display: block; font-size: 0.95rem; opacity: 0.8; margin-top: 0.2em; }

/* A DEMONSTRATION ENTRY HAS TO LOOK LIKE ONE AT A GLANCE. The production build
   publishes no example at all, so these two rules only ever render in a local
   build — which is exactly when somebody is screenshotting the page, and a
   screenshot carries no build flags. The dashed border is the theme's own idiom
   for a thing standing in for the real thing (.artisan__placeholder,
   .site-header__logo-placeholder); the badge is solid and dark because it has
   to win against a photograph. */
.pw__badge {
  display: inline-block;
  margin-top: 0.5em;
  padding: 0.3em 0.6em;
  background: var(--color-leather-dark);
  color: var(--color-button-text);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.pw__notice {
  max-width: 46rem;
  margin: 0 0 1.5rem;
  padding: 0.9em 1em;
  border: 1px dashed var(--color-leather);
  background: var(--color-surface);
  font-size: 0.95rem;
}
.pw__notice strong { letter-spacing: 0.04em; text-transform: uppercase; }
.pw__notice code { font-size: 0.9em; }

/* ---- A POLICY THAT IS NOT IN EFFECT MUST NOT LOOK LIKE ONE THAT IS ----
   The returns policy is drafted but unapproved, and a page of calm prose about
   refunds reads as operative whatever the first paragraph says. The banner is
   loud on purpose, and the three unanswered owner decisions are marked inline
   so they cannot be skimmed past. Both styles disappear from the page when the
   draft does — scripts/test-returns-policy.mjs refuses a page that still
   carries either one while being offered to search engines. */
.policy-draft {
  max-width: 46rem;
  margin: 0 0 1.75rem;
  padding: 1em 1.1em;
  border: 2px solid #9b2c2c;
  border-left-width: 6px;
  background: #fff5f5;
  color: #4a1010;
  font-size: 0.97rem;
}
.policy-draft p { margin: 0; }
.policy-draft strong { letter-spacing: 0.04em; }
/* A <mark> IS A COLOR, AND A COLOR IS NOT AN ANNOUNCEMENT. Screen readers
   do not voice <mark>, so the three decisions Garrett has to answer were
   findable only by looking — and the first person who needs to find them
   may be reviewing this page with a reader. The tag is read aloud and takes
   no room on screen. */
.policy-decision__tag {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}
mark.policy-decision {
  background: #fff3cd;
  border-bottom: 2px solid #b7791f;
  padding: 0.1em 0.25em;
  color: #4a3410;
  font-weight: 600;
}
