/* ==========================================================================
   DIRTY 30's — Leather & Lace
   Hester-style: white ground, generous whitespace, photography doing the
   talking, restrained sans-serif headings, two spot colours used sparingly.
   One stylesheet. No dependencies, no external fonts, no build step.
   ========================================================================== */

:root {
  --bg:         #ffffff;
  --bg-soft:    #f6f4f1;
  --ink:        #141414;
  --ink-soft:   #595650;
  --ink-faint:  #8c8880;
  --rule:       #e2dfd9;
  --red:        #CC0000;
  --navy:       #002D65;

  /* The two spot colours again, for the times they are used as *ink* -
     text, a border, a rule - rather than as a fill behind white type. A
     fill can stay the brand colour in both themes, because white on
     #CC0000 or #002D65 reads either way. Ink cannot: #CC0000 on a near
     black ground is 3.4:1, so dark mode lightens these and leaves the
     fills alone. */
  --red-ink:    var(--red);
  --navy-ink:   var(--navy);

  /* Faint washes behind the warning and notice panels. Alpha over a white
     ground is nearly invisible over a dark one, so these are tokens too. */
  --tint-red:   rgb(204 0 0 / 0.05);
  --tint-navy:  rgb(0 45 101 / 0.05);

  /* The <select> caret, which is a data URI and so cannot take a var()
     inside it - the whole image has to swap. */
  --caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23141414' stroke-width='1.4'/%3E%3C/svg%3E");

  /* The cart barrow is one dark colour in alpha, so dark mode inverts the
     file instead of shipping a light twin of it. */
  --icon-flip: none;

  /* 2700K, the warm end of a domestic bulb, converted to sRGB. Used
     only by the dark-mode button, which glows like a night light. */
  --nightlight:         #ffa757;
  --switch-edge:        rgb(20 20 20 / 0.3);
  --switch-track:       rgb(20 20 20 / 0.07);
  --switch-track-hover: rgb(20 20 20 / 0.13);

  --max:        72rem;
  --measure:    46rem;
  --gutter:     clamp(1.25rem, 5vw, 4rem);

  --sans: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Helvetica Neue",
          "Segoe UI", Roboto, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  color-scheme: light;
}

/* Dark mode is a straight swap of the values above - every rule in this
   file already reads its colours through these tokens, so nothing below
   needs a second copy. The ground is warm (#13110f, not #000) to match the
   warm off-white it replaces, and the navy band keeps its brand colour in
   both themes.

   data-theme is set on <html> by theme.js before first paint. The media
   query is not used directly: the cookie has to be able to override the
   system, and a single attribute does both. */
:root[data-theme="dark"] {
  --bg:         #13110f;
  --bg-soft:    #1e1b18;
  --ink:        #f2efea;
  --ink-soft:   #b5b0a7;
  --ink-faint:  #918c83;
  --rule:       #332f2a;

  --red-ink:    #ff6161;
  --navy-ink:   #85aaea;
  --tint-red:   rgb(255 97 97 / 0.09);
  --tint-navy:  rgb(133 170 234 / 0.10);

  --caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23f2efea' stroke-width='1.4'/%3E%3C/svg%3E");

  --icon-flip: brightness(0) invert(1);

  --switch-edge:        rgb(242 239 234 / 0.34);
  --switch-track:       rgb(242 239 234 / 0.1);
  --switch-track-hover: rgb(242 239 234 / 0.18);

  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 1rem/1.7 var(--sans);
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

img { max-width: 100%; height: auto; display: block; }
[hidden] { display: none !important; }

/* Off screen but still in the document, for headings that would only
   repeat what the control above them already says. Not display:none,
   which would take it out of the accessibility tree as well. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

a { color: var(--navy-ink); text-underline-offset: 0.2em; text-decoration-thickness: 1px; }
a:hover { color: var(--red-ink); }

:where(a, button, select, input, [tabindex]):focus-visible {
  outline: 2px solid var(--navy-ink);
  outline-offset: 3px;
}

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: clamp(3rem, 9vw, 7rem); }

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

h1, h2, h3 { margin: 0; font-weight: 600; line-height: 1.12; text-wrap: balance; }

.eyebrow {
  margin: 0;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* --- masthead ------------------------------------------------------------ */

.masthead {
  position: relative;
  border-bottom: 1px solid var(--rule);
  background: var(--bg);
}
.masthead__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.65rem clamp(0.75rem, 2.5vw, 1.4rem);
  min-height: 4.5rem;
  padding-block: 0.9rem;
  /* Keep the centred lockup clear of the controls, one in each corner.
     Symmetric, so the lockup sits on the true centre of the page rather
     than being pushed off it by clearance on one side only. Each side
     allows for the wider of the two controls plus a little air. */
  padding-inline: clamp(3.8rem, 12vw, 4.25rem);
}

.masthead__brand {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  text-decoration: none;
  color: inherit;
}
.masthead__star { width: clamp(28px, 5vw, 36px); flex: none; }

/* One line beside the star, rather than the two-tier stack this used to be.
   Plain inline flow, not a flex row: the whitespace between the two elements
   in the markup is the word space, and on a narrow screen the line can break
   between them by itself. Each half is nowrap so that break lands between
   "DIRTY 30's" and "Leather & Lace" and nowhere else. One size and one
   tracking throughout; only the weight separates the two halves. */
.masthead__words {
  font-size: clamp(0.85rem, 1.8vw, 1.4rem);
  letter-spacing: 0.1em;
  line-height: 1.1;
  text-transform: uppercase;
}
.masthead__words b,
.masthead__words span { white-space: nowrap; }
.masthead__words b { font-weight: 600; }
.masthead__words span { font-weight: 400; }

.masthead__product {
  font-size: clamp(0.78rem, 2vw, 0.95rem);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* On a phone the lockup has a control on each side rather than open space
   on the left, so everything in the row gives up a little: a smaller
   switch, a slightly smaller star and wordmark, and only as much side
   clearance as the switch actually needs. */
@media (max-width: 30rem) {
  .masthead__inner {
    gap: 0.2rem 0.75rem;
    padding-inline: 2.9rem;
  }
  .masthead__star { width: 26px; }
  .masthead__words { font-size: 0.78rem; letter-spacing: 0.07em; }
  :root[data-theme] .theme-toggle { width: 1.85rem; height: 1.85rem; }
  .theme-toggle__icon { width: 0.95rem; height: 0.95rem; }
}

/* --- the controls, pinned to the corner of the page ---------------------- */

/* The cart used to be pinned here by itself. The switch sits beside it, so
   the pinning moved up to a group and both are laid out inside it. */
.masthead__tools {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  right: var(--gutter);
  z-index: 20;
  display: flex;
  align-items: center;
  gap: clamp(0.6rem, 2vw, 1rem);
}

/* The switch takes the opposite corner from the cart. Its own absolutely
   positioned box, not one box spanning the header, so nothing invisible
   stretches across the middle and swallows clicks meant for the brand. */
.masthead__tools--left { right: auto; left: var(--gutter); }

.cart-fab {
  position: relative;        /* the count badge hangs off this */
  padding: 0.3rem;
  border: 0;
  background: none;
  cursor: pointer;
  line-height: 0;
}
/* The wheelbarrow is a single-colour silhouette in alpha - #17120D at
   every opacity - so dark mode flips it rather than shipping a second
   file: brightness(0) flattens the colour to black, invert(1) takes it to
   white, and neither touches the alpha that does the drawing. */
.cart-fab img {
  width: clamp(2rem, 4.5vw, 2.5rem);
  height: auto;
  filter: var(--icon-flip);
}
.cart-fab__count {
  position: absolute;
  top: -0.3rem; right: -0.35rem;
  display: grid; place-items: center;
  min-width: 1.25rem; height: 1.25rem;
  padding-inline: 0.3rem;
  border-radius: 999px;
  background: var(--red);
  color: #fff;
  font: 600 0.7rem/1 var(--sans);
  box-shadow: 0 0 0 2px var(--bg);
}
.cart-fab[data-empty="true"] .cart-fab__count { display: none; }

/* --- light / dark button ------------------------------------------------- */

/* Hidden until theme.js has run. It sets data-theme on <html> as its first
   act, so with scripting off a control that could not switch anything never
   appears at all. */
.theme-toggle { display: none; }

:root[data-theme] .theme-toggle {
  display: grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: 1px solid var(--switch-edge);
  border-radius: 999px;
  background: var(--switch-track);
  color: var(--ink);
  cursor: pointer;
  line-height: 0;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.18s ease, border-color 0.18s ease,
              box-shadow 0.25s ease, color 0.25s ease;
}
.theme-toggle:hover {
  background: var(--switch-track-hover);
  border-color: var(--ink-faint);
}

/* One glyph, naming the mode you are in rather than the one you would get
   by pressing it. Same reading as the switch it replaced. */
.theme-toggle__icon {
  width: 1.05rem;
  height: 1.05rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.theme-toggle__icon--moon { display: none; }
.theme-toggle[aria-checked="true"] .theme-toggle__icon--sun { display: none; }
.theme-toggle[aria-checked="true"] .theme-toggle__icon--moon { display: block; }

/* In the dark it is a night light. 2700K is the warm end of a domestic
   bulb, and #ffa757 is that colour temperature converted to sRGB, so the
   glow is the real number rather than a guessed orange.

   Three shadows and no animation: a tight ring for the bulb, a wide soft
   one for the spill it throws on the masthead, and an inset so the disc
   itself looks lit from within rather than outlined. Night lights do not
   pulse, and a thing that breathes in the corner of a shop page would be
   a distraction with nothing to say. */
:root[data-theme] .theme-toggle[aria-checked="true"] {
  color: var(--nightlight);
  border-color: rgb(255 167 87 / 0.45);
  background:
    radial-gradient(circle at 50% 50%,
                    rgb(255 167 87 / 0.22), rgb(255 167 87 / 0.04) 70%);
  box-shadow:
    0 0 0.45rem rgb(255 167 87 / 0.5),
    0 0 1.5rem rgb(255 167 87 / 0.3),
    inset 0 0 0.55rem rgb(255 167 87 / 0.22);
}
:root[data-theme] .theme-toggle[aria-checked="true"]:hover {
  border-color: rgb(255 167 87 / 0.7);
  box-shadow:
    0 0 0.55rem rgb(255 167 87 / 0.65),
    0 0 1.9rem rgb(255 167 87 / 0.4),
    inset 0 0 0.6rem rgb(255 167 87 / 0.3);
}
/* The glyph is the filament. */
.theme-toggle[aria-checked="true"] .theme-toggle__icon {
  filter: drop-shadow(0 0 2.5px rgb(255 167 87 / 0.85));
}

@media (prefers-reduced-motion: reduce) {
  .theme-toggle { transition: none; }
}

/* --- hero ---------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: clamp(24rem, 76vh, 44rem);
  display: grid;
  align-content: end;            /* button sits in the lower half */
  justify-items: center;
  padding: clamp(2.5rem, 8vw, 6rem) var(--gutter) clamp(3rem, 12vh, 7rem);
  background-color: #2b2420;
  background-image: url("/assets/img/hero-1600.jpg");
  background-size: cover;
  background-position: center;
  overflow: hidden;
}
@media (min-width: 1100px) { .hero { background-image: url("/assets/img/hero-2400.jpg"); } }
@media (max-width: 36rem)  { .hero { background-image: url("/assets/img/hero-900.jpg"); } }

/* A soft vignette at the foot so the button always has something to sit on. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgb(16 13 10 / 0) 45%, rgb(16 13 10 / 0.45));
}
.hero__cta { position: relative; }

/* --- product ------------------------------------------------------------- */

.product {
  display: grid;
  gap: clamp(1.75rem, 5vw, 4rem);
  align-items: start;
}
@media (min-width: 52rem) { .product { grid-template-columns: 1.1fr 1fr; } }

.gallery { display: grid; gap: 0.6rem; }
.gallery__main {
  display: block; width: 100%; padding: 0; border: 0;
  background: var(--bg-soft); cursor: zoom-in; font: inherit; line-height: 0;
}
.gallery__thumbs { display: grid; grid-template-columns: repeat(auto-fill, 4.5rem); gap: 0.6rem; }
.gallery__thumbs button {
  padding: 0; border: 1px solid transparent; background: var(--bg-soft);
  cursor: pointer; line-height: 0;
}
.gallery__thumbs button.is-active { border-color: var(--ink); }
.gallery__thumbs button:not(.is-active) { opacity: 0.55; }

.media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--bg-soft); }
.media img { width: 100%; height: 100%; object-fit: cover; }
.gallery__thumbs .media { aspect-ratio: 1; }

/* Kept for the heading itself, which is .visually-hidden on the shop page -
   the <select> above it already names the product. Restore the class on
   its own if a product ever gets a page where the name has to show. */
.product__name {
  margin: 0.5rem 0 0;
  font-size: clamp(1.4rem, 3.4vw, 2rem);
  font-weight: 600;
  letter-spacing: 0.01em;
}
/* Description first, then price - so the margins run desc -> small gap ->
   price -> larger gap -> buy row. */
.product__desc  { margin: 0 0 1rem; color: var(--ink-soft); max-width: 42ch; }
.product__price { margin: 0 0 1.75rem; font-size: 1.15rem; color: var(--ink-soft); }

.field { display: grid; gap: 0.45rem; margin-bottom: 1.25rem; max-width: 22rem; }
.field label {
  font-size: 0.68rem; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-faint);
}
.field select {
  appearance: none;
  width: 100%;
  padding: 0.85rem 2.5rem 0.85rem 1rem;
  border: 1px solid var(--rule);
  border-radius: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 0.98rem/1.2 var(--sans);
  cursor: pointer;
  /* caret */
  background-image: var(--caret);
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 0.7rem;
}
.field select:hover { border-color: var(--ink-faint); }

.buy-row { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: stretch; margin-bottom: 2rem; }

.qty { display: inline-flex; border: 1px solid var(--rule); }
.qty button {
  width: 2.6rem; border: 0; background: none; color: var(--ink);
  font: 400 1.1rem/1 var(--sans); cursor: pointer;
}
.qty button:hover { color: var(--red-ink); }
.qty input {
  width: 3rem; border: 0; border-inline: 1px solid var(--rule);
  background: none; color: var(--ink); text-align: center;
  font: 400 0.95rem/1 var(--mono); -moz-appearance: textfield;
}
.qty input::-webkit-outer-spin-button,
.qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.9rem 2rem;
  border: 1px solid var(--ink);
  background: var(--ink);
  /* var(--bg), not #fff: this is ink-coloured fill, so the type on it has
     to be the page ground or it disappears when the two swap. */
  color: var(--bg);
  font: 500 0.72rem/1 var(--sans);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.14s ease, border-color 0.14s ease, color 0.14s ease;
}
.btn:hover { background: var(--navy); border-color: var(--navy); color: #fff; }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: 0.45; cursor: not-allowed; }
.btn--block { width: 100%; }
/* One red for every primary action; stays red on hover rather than switching. */
.btn--red,
.btn--shop,
.btn[data-add-to-cart] {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}
.btn--red:hover,
.btn--shop:hover,
.btn[data-add-to-cart]:hover { background: #a80000; border-color: #a80000; color: #fff; }

/* The secondary route into Venmo, in the brand navy rather than the red kept
   for primary actions. Same treatment as the red: darkens on hover instead of
   switching colour. */
.btn--navy { background: var(--navy); border-color: var(--navy); color: #fff; }
.btn--navy:hover { background: #001c42; border-color: #001c42; color: #fff; }

.btn--shop {
  padding: 1.05rem 2.75rem;
  font-size: 0.78rem;
  letter-spacing: 0.24em;
  box-shadow: 0 0.5rem 1.75rem rgb(0 0 0 / 0.3);
}
.btn--ghost { background: none; color: var(--ink); border-color: var(--rule); }
.btn--ghost:hover { background: none; color: var(--red-ink); border-color: var(--red-ink); }

.specs { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.specs li {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: 0.7rem 0; border-bottom: 1px solid var(--rule); font-size: 0.9rem;
}
.specs .k { color: var(--ink-faint); font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; }
.specs .v { color: var(--ink-soft); text-align: right; }

/* --- lightbox ------------------------------------------------------------ */

.lightbox {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center; gap: 1rem;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgb(10 10 10 / 0.94);
  opacity: 0; transition: opacity 0.18s ease; cursor: zoom-out;
}
.lightbox[data-open="true"] { opacity: 1; }
.lightbox[hidden] { display: none !important; }
@media (prefers-reduced-motion: reduce) { .lightbox { transition: none; } }
.lightbox__img { max-width: 100%; max-height: 84vh; object-fit: contain; }
.lightbox__close {
  position: absolute; top: calc(env(safe-area-inset-top, 0px) + 0.75rem); right: 0.75rem;
  width: 2.6rem; height: 2.6rem; border: 1px solid rgb(255 255 255 / 0.3);
  background: none; color: #fff; font-size: 1.4rem; line-height: 1; cursor: pointer;
}
.lightbox__hint {
  margin: 0; color: rgb(255 255 255 / 0.55);
  font-size: 0.66rem; letter-spacing: 0.22em; text-transform: uppercase;
}

/* --- cart drawer --------------------------------------------------------- */

.drawer-overlay {
  position: fixed; inset: 0; z-index: 40; background: rgb(10 10 10 / 0.4);
  opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
}
.drawer-overlay[data-open="true"] { opacity: 1; pointer-events: auto; }

.drawer {
  position: fixed; top: 0; right: 0; z-index: 50;
  display: flex; flex-direction: column;
  width: min(25rem, 100%); height: 100dvh;
  background: var(--bg);
  border-left: 1px solid var(--rule);
  box-shadow: -1.5rem 0 3rem rgb(0 0 0 / 0.08);
  transform: translateX(101%);
  transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
}
.drawer[data-open="true"] { transform: none; }
@media (prefers-reduced-motion: reduce) { .drawer, .drawer-overlay { transition: none; } }

.drawer__head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.15rem var(--gutter); border-bottom: 1px solid var(--rule);
}
.drawer__head h2 { font-size: 0.72rem; letter-spacing: 0.2em; text-transform: uppercase; font-weight: 500; }
.drawer__close { border: 0; background: none; color: var(--ink-faint); font-size: 1.5rem; line-height: 1; padding: 0.2rem 0.4rem; cursor: pointer; }
.drawer__close:hover { color: var(--red-ink); }
.drawer__body { flex: 1; overflow-y: auto; padding: 0.5rem var(--gutter); }
.drawer__empty { text-align: center; padding: 3rem 0; color: var(--ink-faint); font-size: 0.9rem; }

.line { display: grid; grid-template-columns: 3.5rem 1fr auto; gap: 0.85rem; align-items: start; padding: 1rem 0; border-bottom: 1px solid var(--rule); }
.line__media { aspect-ratio: 1; background: var(--bg-soft); }
.line__media img { width: 100%; height: 100%; object-fit: cover; }
.line__name { margin: 0 0 0.2rem; font-size: 0.92rem; font-weight: 500; }
.line__meta { margin: 0; font-size: 0.78rem; color: var(--ink-faint); }
.line__price { margin: 0; font-size: 0.9rem; white-space: nowrap; }
.line__remove { border: 0; background: none; padding: 0.2rem 0; color: var(--ink-faint); font-size: 0.72rem; cursor: pointer; text-decoration: underline; }
.line__remove:hover { color: var(--red-ink); }
.line .qty { margin-top: 0.5rem; }
.line .qty button { width: 1.9rem; }
.line .qty input { width: 2.3rem; font-size: 0.82rem; }

.drawer__foot { padding: 1.15rem var(--gutter); border-top: 1px solid var(--rule); }
.totals { display: grid; gap: 0.35rem; margin-bottom: 1rem; font-size: 0.9rem; }
.totals div { display: flex; justify-content: space-between; gap: 1rem; }
.totals .k { color: var(--ink-faint); }
.totals__sub { font-size: 1.05rem; font-weight: 500; }
.note { margin: 0.75rem 0 0; text-align: center; font-size: 0.7rem; letter-spacing: 0.08em; color: var(--ink-faint); }
/* A note that runs to several lines is prose, not a caption: centred it
   leaves a ragged stack under a full-width button. Left aligned it
   starts on the button's own left edge. */
.note--left { text-align: left; line-height: 1.7; }

.alert { margin: 0 0 0.9rem; padding: 0.6rem 0.8rem; border: 1px solid var(--red-ink); background: var(--tint-red); font-size: 0.85rem; }

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

/* The footer is the one dark band on the site. White at 72% on #002D65 gives
   a 7.7:1 contrast ratio, so the secondary lines stay readable rather than
   just looking faded. */
.site-footer {
  background: var(--navy);
  padding-block: clamp(2.5rem, 6vw, 3.5rem);
  text-align: center;
  font-size: 0.82rem;
  color: rgb(255 255 255 / 0.72);
}
.site-footer p { margin: 0.45rem 0 0; }
.site-footer a { color: rgb(255 255 255 / 0.85); }
.site-footer a:hover { color: #fff; }

/* Tristar beside the wordmark, echoing the masthead lockup. The type size
   lives on the lockup so the star can be sized in em and track it: change the
   wordmark size and the star follows instead of drifting out of proportion. */
.site-footer__lockup {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  margin: 0;
  font-size: clamp(0.76rem, 2vw, 0.88rem);
}
/* p.<class> throughout this block, because ".site-footer p" above is one
   class plus one element and beats a bare class selector. */
p.site-footer__copy { margin: 0 0 0.7rem; }
.site-footer__star { height: 1.7em; width: auto; flex: none; }
/* p.<class>, not just .<class>: ".site-footer p" above is one class plus one
   element, so a bare class selector loses to it and the generic paragraph
   margin-top survives - which then throws the star 3.6px high, because
   align-items centres the margin box, not the text. */
p.site-footer__brand {
  margin: 0;
  font-size: 1em;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #fff;
}
/* Only the weight separates the two halves, as in the masthead. */
.site-footer__brand span { font-weight: 400; }

/* The policy links, on the line the Venmo sentence used to hold. Centred and
   allowed to wrap on a phone, where all three will not sit side by side. */
.site-footer__legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.15rem 0.5rem;
  margin: 0.9rem 0 0;
  padding: 0;
  list-style: none;
}
/* The separator hangs off the item rather than sitting between two of them,
   so a wrapped line never starts with a stray dot. */
.site-footer__legal li + li::before {
  content: "\00b7";
  margin-right: 0.5rem;
  color: rgb(255 255 255 / 0.4);
}

/* Last line of the footer again, so it gets the gap that separates it
   from the block above rather than sitting inside that block. */
/* align-items matters here: without it the items stretch and each glyph is
   left sitting at the TOP of the row, so the moment one icon is taller than
   the others everything else rides up and the tall one's feet hang below the
   line. Invisible while every mark is the same height, and a trap the day
   one of them is not. */
.social {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.4rem;
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
}
.social a { display: grid; place-items: center; color: rgb(255 255 255 / 0.72); }
.social a:hover { color: #fff; }
.social svg { width: 1.35rem; height: 1.35rem; fill: currentColor; }

/* The Instagram glyph is drawn as strokes rather than a filled trace, so it
   carries the same optical weight as the YouTube mark beside it. Meta allows
   the glyph in any solid colour provided the geometry is untouched. */
.social .ig { fill: none; stroke: currentColor; stroke-width: 1.9; }
.social .ig__dot { fill: currentColor; stroke: none; }

/* --- simple pages (thanks / 404) ----------------------------------------- */

.plain { text-align: center; max-width: var(--measure); margin-inline: auto; }
.plain h1 { font-size: clamp(1.6rem, 4vw, 2.3rem); margin-bottom: 0.75rem; }
.plain p { color: var(--ink-soft); }
.plain .btn { margin-top: 1.75rem; }

/* --- policy pages (privacy / returns) ------------------------------------ */
/* Left aligned and held to the reading measure, unlike .plain above, which is
   centred because it carries three lines rather than a page of them. */

.legal { max-width: var(--measure); margin-inline: auto; }
.legal h1 { font-size: clamp(1.6rem, 4vw, 2.3rem); }
.legal .eyebrow { margin: 0.9rem 0 2rem; }
.legal h2 {
  margin: 2.5rem 0 0.7rem;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.legal p { margin: 0 0 1rem; color: var(--ink-soft); }
.legal ul { margin: 0 0 1rem; padding-left: 1.15rem; color: var(--ink-soft); }
.legal li { margin-bottom: 0.3rem; }
.legal b { font-weight: 600; color: var(--ink); }
/* An underline that is not a link: full-strength ink so it reads as
   emphasis rather than a dead anchor, and the same underline metrics
   as the real links beside it. */
.legal u {
  color: var(--ink);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}
.legal code {
  font: 400 0.9em/1 var(--mono);
  padding: 0.15em 0.35em;
  background: var(--bg-soft);
}
.legal .btn { margin-top: 2.25rem; }

/* --- checkout, pay, admin ------------------------------------------------ */
/* Added with the Venmo rebuild. The Stripe version had no pages of its own
   for these: Stripe hosted the address form and the payment screen. */

/* Text inputs were never styled before, because the only form control on the
   old site was the variant <select>. Match it exactly. */
.field input {
  width: 100%;
  padding: 0.85rem 1rem;
  border: 1px solid var(--rule);
  border-radius: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 0.98rem/1.2 var(--sans);
  -webkit-appearance: none;
  appearance: none;
}
.field input:hover { border-color: var(--ink-faint); }
.field input[aria-invalid="true"],
.field select[aria-invalid="true"] { border-color: var(--red); }
.field__hint { font-size: 0.75rem; color: var(--ink-faint); }
.field__opt {
  font-weight: 400; letter-spacing: 0.08em; text-transform: none;
  color: var(--ink-faint);
}

/* --- contact form -------------------------------------------------------- */
/* Reuses .co-form from the checkout, so only what is new to this page lives
   here: the textarea, the honeypot and the Turnstile widget's slot. */

.contact-form { margin-top: 2.5rem; max-width: 34rem; }

/* Matched to .field input above rather than inherited, because a textarea
   takes neither the font nor the box sizing from it. */
.field textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  border: 1px solid var(--rule);
  border-radius: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 0.98rem/1.5 var(--sans);
  resize: vertical;
  -webkit-appearance: none;
  appearance: none;
}
.field textarea:hover { border-color: var(--ink-faint); }
.field textarea[aria-invalid="true"] { border-color: var(--red); }

/* The honeypot. Off screen rather than display:none, because some bots skip
   anything that is outright hidden - and left out of the tab order and the
   accessibility tree so nobody using a keyboard or a screen reader can land
   in it by accident. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.turnstile:not(:empty) { margin-bottom: 1.5rem; }

/* The confirmation that replaces the form once a message is away. */
#contact-sent { margin-top: 2.5rem; }
#contact-sent h2 {
  margin-bottom: 0.75rem;
  font-size: clamp(1.2rem, 3vw, 1.5rem);
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
}

hr.rule { border: 0; border-top: 1px solid var(--rule); margin: 2.5rem 0; }

.checkout h1,
.pay h1 { font-size: clamp(1.6rem, 4vw, 2.3rem); margin-bottom: 1.5rem; }

/* The Venmo wordmark stands on its own line rather than running into the
   sentence, which is what their brand guidelines require. The margin below
   the eyebrow is the logo's clear space. */
.pay__title { display: grid; justify-items: start; gap: 0.55rem; }
.pay__title-pre { display: block; line-height: 1; }
.pay__title-mark {
  display: block;
  width: clamp(8.5rem, 30vw, 11rem);
  height: auto;
}
.checkout__cols { display: grid; gap: clamp(2rem, 5vw, 4rem); }
@media (min-width: 52rem) {
  .checkout__cols { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
}

.co-form h2,
.co-review h2 {
  font-size: 0.68rem; font-weight: 500; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--ink-faint); margin-bottom: 1.25rem;
}
/* Marks the required fields. Decorative only - every input it sits beside
   already carries the `required` attribute, which is what a screen reader
   announces, so the glyph is aria-hidden rather than read out as "star"
   on top of it. letter-spacing is reset because the label tracks at 0.2em,
   which would otherwise push the asterisk away from its word. */
.req {
  color: var(--red-ink);
  letter-spacing: normal;
  font-size: 1.15em;
  line-height: 1;
}
.co-form .field { max-width: none; }
.co-form .btn--block { margin-top: 0.5rem; }

/* ZIP / city / state share a row once there is room for it. ZIP leads
   because zip-lookup.js fills the other two from it, and a field that
   fills itself has to come before the fields it fills. */
.field-row { display: grid; gap: 0 1rem; }
@media (min-width: 30rem) {
  .field-row { grid-template-columns: 8rem 1fr 6.5rem; }
}

.co-review {
  align-self: start;
  padding: clamp(1.25rem, 3vw, 1.75rem);
  background: var(--bg-soft);
}
.co-line {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: 0.6rem 0; border-bottom: 1px solid var(--rule);
  font-size: 0.9rem;
}
.co-line:last-of-type { border-bottom: 0; }
.co-line__name { color: var(--ink); }
.co-line__qty { color: var(--ink-faint); margin-left: 0.4rem; }
.co-line__price { white-space: nowrap; }
.co-review .totals { margin-top: 1rem; }
.totals__grand {
  padding-top: 0.5rem; border-top: 1px solid var(--rule);
  font-size: 1.05rem; font-weight: 500;
}
.totals__grand .k { color: var(--ink); }

/* --- pay ---------------------------------------------------------------- */

.pay { max-width: var(--measure); margin-inline: auto; }
.pay__ref { margin: 0 0 1.5rem; font-size: 0.9rem; color: var(--ink-faint); }
.pay__ref b { font-family: var(--mono); color: var(--ink); letter-spacing: 0.05em; }

.pay__amount {
  display: grid; gap: 0.3rem; justify-items: center; text-align: center;
  padding: clamp(1.5rem, 4vw, 2.25rem) 1rem;
  background: var(--bg-soft); margin-bottom: 1.75rem;
}
.pay__amount-k {
  font-size: 0.68rem; font-weight: 500; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--ink-faint);
}
.pay__amount-v {
  font-size: clamp(2.2rem, 8vw, 3.2rem); font-weight: 500;
  line-height: 1; letter-spacing: -0.01em;
}
.pay__amount-to { font-size: 0.9rem; color: var(--ink-soft); }
.pay__amount-to b { font-family: var(--mono); color: var(--ink); }

.pay__act { margin-bottom: 2rem; }
/* A full cart with a long address reaches a 69-module symbol, which at the
   old 16rem left only ~3.3 CSS px per module on a phone. */
.pay__qr {
  width: min(19rem, 82vw); margin: 0 auto 1rem;
  padding: 0.75rem; background: #fff; border: 1px solid var(--rule);
}
.pay__qr svg { display: block; width: 100%; height: auto; }
.pay__qr-cap {
  margin: 0 auto; max-width: 38ch; text-align: center;
  font-size: 0.85rem; color: var(--ink-soft);
}

.pay__copy { display: grid; gap: 0.5rem; margin-bottom: 1.75rem; }
.copyrow {
  display: grid; grid-template-columns: 4.5rem minmax(0, 1fr) auto;
  gap: 0.75rem; align-items: center;
  padding: 0.7rem 0.85rem; border: 1px solid var(--rule);
}
.copyrow__k {
  font-size: 0.68rem; font-weight: 500; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-faint);
}
.copyrow__v {
  font: 400 0.82rem/1.45 var(--mono);
  overflow-wrap: anywhere; min-width: 0;
}
.copyrow__btn {
  border: 1px solid var(--ink); background: none; color: var(--ink);
  padding: 0.35rem 0.75rem; cursor: pointer;
  font: 500 0.68rem/1 var(--sans); letter-spacing: 0.14em;
  text-transform: uppercase; white-space: nowrap;
}
.copyrow__btn:hover { background: var(--ink); color: var(--bg); }
.copyrow__status {
  margin: 0; min-height: 1.2em;
  font-size: 0.78rem; color: var(--ink-faint);
}

/* The one thing on the page the customer must not casually undo. */
.pay__warn {
  padding: 0.9rem 1rem; margin-bottom: 1.75rem;
  border-left: 3px solid var(--red-ink); background: var(--tint-red);
}
.pay__warn p { margin: 0; font-size: 0.9rem; color: var(--ink-soft); }
.pay__warn b { color: var(--ink); }

/* --- admin -------------------------------------------------------------- */

.admin { max-width: var(--max); }
.admin h1 { font-size: clamp(1.4rem, 3.5vw, 2rem); margin-bottom: 1.5rem; }
.admin__gate { max-width: 22rem; }
.admin__bar {
  display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center;
  justify-content: space-between; margin-bottom: 1.5rem;
}
.admin__count { margin: 0; font-size: 0.85rem; color: var(--ink-faint); }
.order {
  padding: 1.1rem 0; border-bottom: 1px solid var(--rule);
  display: grid; gap: 0.5rem;
}
.order__top {
  display: flex; flex-wrap: wrap; gap: 0.6rem 1rem;
  align-items: baseline; justify-content: space-between;
}
.order__ref {
  font: 500 0.95rem/1 var(--mono); letter-spacing: 0.05em;
}
.order__when { font-size: 0.78rem; color: var(--ink-faint); }
.order__total { font-size: 1rem; font-weight: 500; white-space: nowrap; }
.order__items { margin: 0; font-size: 0.85rem; color: var(--ink-soft); }
.order__addr {
  margin: 0; font: 400 0.85rem/1.55 var(--mono); color: var(--ink);
  overflow-wrap: anywhere;
}
.order__note {
  margin: 0; font-size: 0.75rem; color: var(--ink-faint);
  overflow-wrap: anywhere;
}

/* Shown inside Instagram/Facebook style browsers, which cannot hand a link
   to another app, and when the customer comes back from Venmo. */
.pay__inapp {
  padding: 0.9rem 1rem; margin-top: 1rem;
  border-left: 3px solid var(--navy-ink); background: var(--tint-navy);
}
.pay__inapp p { margin: 0 0 0.5rem; font-size: 0.9rem; color: var(--ink-soft); }
.pay__inapp p:last-child { margin-bottom: 0; }
.pay__inapp .note { text-align: left; }

.pay__help { margin-top: 1rem; }
.pay__help summary {
  cursor: pointer; font-size: 0.78rem; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint);
  padding: 0.4rem 0;
}
.pay__help summary:hover { color: var(--ink); }
.pay__help p { margin: 0.75rem 0; font-size: 0.9rem; color: var(--ink-soft); }

/* The closing step is centred; .btn is inline-flex, so text-align carries it. */
.pay__finish { text-align: center; }
.pay__finish p { margin: 0 0 1.25rem; }
.pay__finish p:last-child { margin-bottom: 0; }

.pay__back {
  padding: 0.9rem 1rem; margin-bottom: 1.25rem;
  border-left: 3px solid var(--red-ink); background: var(--tint-red);
}
.pay__back p { margin: 0; font-size: 0.95rem; color: var(--ink-soft); }
.pay__back b { color: var(--ink); }

/* Copy buttons on each stored order. The address in the Venmo note comes back
   with "+" for every space, so this is what you actually paste into a
   shipping form. */
.order__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0; }
