/* Ori's customer-facing catalogs — wholesale (/mayorista/) and public
   (/catalogo/). One stylesheet, two surfaces.

   The rules this obeys: white ground, near-black text, 1px hairlines, square
   corners, no shadows, no rotation, no simulated materials, no decorative
   anything. Hierarchy comes from position, scale of PHOTOGRAPHS, and muting —
   never from ornament. Monospace carries the utility register (SKU, price,
   quantity); Archivo carries names and prose.

   Photos are the design. Everything else is scaffolding for photos. */

@font-face {
  font-family: 'Archivo';
  src: url('fonts/archivo-var.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: 'Plex Mono';
  src: url('fonts/plexmono-400.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Plex Mono';
  src: url('fonts/plexmono-500.woff2') format('woff2');
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: 'Plex Mono';
  src: url('fonts/plexmono-600.woff2') format('woff2');
  font-weight: 600;
  font-display: swap;
}

:root {
  --ink: #111;
  --muted: #767676;   /* 4.6:1 on white — muted but still legible */
  --faint: #949494;
  --line: #e0e0e0;
  --ground: #fff;
  --accent: #111;
  --sans: 'Archivo', system-ui, -apple-system, sans-serif;
  --mono: 'Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --gap: 24px;
  --bar: 68px;        /* sticky order bar */
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }
/* the full-bleed map spans 100vw, which on scrollbar-bearing browsers
   overhangs by the scrollbar's width — clip it rather than grow a
   horizontal scroll the width of a hairline */
body { overflow-x: clip; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  font-synthesis-weight: none;
  /* a column the height of the window, so a page with little on it still
     puts its footer at the foot of the viewport instead of mid-screen */
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

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

a { color: inherit; }

/* ---------- frame ---------- */

/* width:100% matters: as a flex item of the column body, margin:0 auto
   alone would shrink-to-fit instead of filling to the 1180px cap */
.wrap { width: 100%; max-width: 1180px; margin: 0 auto; padding: 0 20px; }

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 22px 0 18px; border-bottom: 1px solid var(--line);
}
.topbar .mark { display: flex; align-items: center; gap: 12px; }
.topbar svg { display: block; }

.who {
  font-family: var(--mono); font-size: 12px; letter-spacing: .02em;
  color: var(--muted); text-transform: uppercase;
}

.intro { padding: 40px 0 32px; max-width: 62ch; }
.intro h1 {
  margin: 0 0 10px; font-size: clamp(26px, 4.5vw, 40px);
  font-weight: 500; letter-spacing: -.02em; line-height: 1.15;
}
.intro p { margin: 0; color: var(--muted); font-size: 15px; }
.intro .note {
  margin-top: 14px; font-family: var(--mono); font-size: 12.5px;
  color: var(--ink); border-left: 2px solid var(--ink); padding-left: 12px;
}

/* ---------- filters ---------- */

.filters {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 0 0 28px;
}
.filters button {
  font-family: var(--mono); font-size: 12px; text-transform: uppercase;
  letter-spacing: .04em; padding: 7px 12px; background: none; color: var(--muted);
  border: 1px solid var(--line); cursor: pointer;
}
.filters button[aria-pressed="true"] { color: var(--ground); background: var(--ink); border-color: var(--ink); }

/* ---------- the product list ---------- */

.product {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: var(--gap);
  padding: 44px 0;
  border-top: 1px solid var(--line);
  align-items: start;
}
.product:first-of-type { border-top: none; }
/* the tag filter sets [hidden]; without this the grid display wins and the
   filter "works" while hiding nothing (same trap .orderbar guards against) */
.product[hidden] { display: none; }

.shots { display: grid; grid-template-columns: 1fr; gap: 8px; }
.shots .lead { background: #f7f7f7; aspect-ratio: 4 / 5; }
.shots .lead img { width: 100%; height: 100%; object-fit: cover; }
.shots .strip { display: grid; grid-auto-flow: column; grid-auto-columns: 88px; gap: 8px; overflow-x: auto; }
.shots .strip img { aspect-ratio: 1; object-fit: cover; background: #f7f7f7; }

.meta h2 {
  margin: 0 0 4px; font-size: 23px; font-weight: 500; letter-spacing: -.01em;
}
.meta .tags {
  font-family: var(--mono); font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--faint); margin-bottom: 14px;
}
.meta .desc { margin: 0 0 22px; color: #333; font-size: 15px; max-width: 52ch; }
.meta .desc:empty { display: none; }

/* colorway rows — the line-sheet register */

table.ways { width: 100%; border-collapse: collapse; font-size: 14px; }
table.ways th {
  text-align: left; font-family: var(--mono); font-weight: 500; font-size: 11px;
  text-transform: uppercase; letter-spacing: .06em; color: var(--faint);
  padding: 0 0 8px; border-bottom: 1px solid var(--line);
}
table.ways th.num, table.ways td.num { text-align: right; }
table.ways td { padding: 12px 0; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.ways .swatch { display: flex; align-items: center; gap: 10px; }
table.ways .swatch img { width: 40px; height: 40px; object-fit: cover; background: #f7f7f7; flex: none; }
table.ways .name { font-size: 14.5px; }
table.ways .sku { font-family: var(--mono); font-size: 11px; color: var(--faint); letter-spacing: .02em; }
table.ways .price { font-family: var(--mono); font-size: 14px; white-space: nowrap; }
table.ways .msrp { font-family: var(--mono); font-size: 11.5px; color: var(--faint); }

/* quantity stepper */

.qty { display: inline-flex; align-items: stretch; border: 1px solid var(--line); }
.qty button {
  width: 34px; height: 34px; border: none; background: none; cursor: pointer;
  font-family: var(--mono); font-size: 15px; color: var(--ink); line-height: 1;
}
.qty button:disabled { color: #ccc; cursor: default; }
.qty input {
  width: 42px; border: none; border-left: 1px solid var(--line);
  border-right: 1px solid var(--line); text-align: center;
  font-family: var(--mono); font-size: 14px; color: var(--ink);
  -moz-appearance: textfield; background: none;
}
.qty input::-webkit-outer-spin-button, .qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.qty input:focus { outline: 2px solid var(--ink); outline-offset: -2px; }
tr.picked td { background: #fafafa; }

/* the wholesale price names itself only when the column headers are gone */
.plabel { display: none; }

/* on a phone the three columns crushed each other — each colourway becomes
   a small card instead: the swatch line full-width, then price facts and
   the stepper sharing the second row */
@media (max-width: 640px) {
  table.ways.sheet, table.ways.sheet tbody { display: block; }
  table.ways.sheet thead { display: none; }
  table.ways.sheet tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    align-items: center; gap: 2px 14px;
    padding: 12px 0; border-bottom: 1px solid var(--line);
  }
  table.ways.sheet td { display: block; border: 0; padding: 0; }
  table.ways.sheet td:first-child { grid-column: 1 / -1; }
  table.ways.sheet td.num { text-align: left; }
  table.ways.sheet td.num:last-child { text-align: right; }
  table.ways.sheet .plabel {
    display: inline; font-family: var(--mono); font-size: 11.5px;
    color: var(--faint); text-transform: uppercase; letter-spacing: .05em;
  }
  tr.picked td { background: none; }
  table.ways.sheet tr.picked { background: #fafafa; }
}

/* ---------- the wholesale sheet, breathing ---------- */

/* one wide photograph between the greeting and the numbers — the buyer
   deciding on shelf space sees hands and fleece before prices */
.wbreath { margin: 0 0 36px; }
.wbreath img { width: 100%; max-height: 40svh; object-fit: cover; }
.wbreath figcaption {
  margin-top: 8px; font-size: 15px; color: var(--ink);
}

/* the sheet reads at a document's measure; the freed leather rides beside
   it on wide screens (pointer-driven — phones and print never see it) */
.sheetrail { display: none; }
@media (min-width: 900px) {
  .sheetcols {
    display: grid; grid-template-columns: minmax(0, 780px) minmax(220px, 1fr);
    gap: 40px; align-items: start;
  }
  .sheetmain { min-width: 0; }
  .sheetrail {
    display: block; position: sticky; top: 24px;
  }
  .sheetrail img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; background: #f7f7f7; }
  .sheetrail .railname {
    margin-top: 8px; font-family: var(--mono); font-size: 11.5px;
    color: var(--muted); text-transform: uppercase; letter-spacing: .05em;
  }
}

/* the verifiable nouns, one quiet line beside the numbers */
.wproof {
  font-family: var(--mono); font-size: 11.5px; color: var(--muted);
  margin: -14px 0 20px; max-width: 52ch;
}

/* the footer's first line is the house speaking, not a SKU */
.foot .footvoice { font-family: var(--sans); font-size: 13px; color: var(--ink); }

/* the print cover: nothing on screen, the first page on paper */
.pdfcover { display: none; }

/* ---------- sticky order bar ---------- */

.orderbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  background: var(--ground); border-top: 1px solid var(--ink);
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom));
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.orderbar[hidden] { display: none; }
.orderbar .sum { font-family: var(--mono); font-size: 13px; line-height: 1.35; }
.orderbar .sum b { font-weight: 600; font-size: 15px; }
.orderbar .sum span { color: var(--muted); display: block; }

.btn {
  font-family: var(--sans); font-size: 15px; font-weight: 500;
  padding: 12px 22px; border: 1px solid var(--ink); background: var(--ink);
  color: var(--ground); cursor: pointer; text-decoration: none; display: inline-block;
}
.btn.ghost { background: none; color: var(--ink); }
.btn:disabled { opacity: .4; cursor: default; }

body.has-bar { padding-bottom: calc(var(--bar) + 20px); }

/* ---------- order form ---------- */

.sheet { max-width: 620px; margin: 0 auto; padding: 40px 0 60px; }
.sheet h1 { font-size: 26px; font-weight: 500; margin: 0 0 6px; letter-spacing: -.02em; }
.sheet .lede { color: var(--muted); margin: 0 0 28px; font-size: 15px; }

.field { margin-bottom: 18px; }
.field label {
  display: block; font-family: var(--mono); font-size: 11px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted); margin-bottom: 6px;
}
.field input, .field textarea {
  width: 100%; padding: 11px 12px; border: 1px solid var(--line);
  font-family: var(--sans); font-size: 16px; color: var(--ink); background: var(--ground);
}
.field input:focus, .field textarea:focus { outline: none; border-color: var(--ink); }
.field textarea { min-height: 84px; resize: vertical; }
.field .req { color: var(--ink); }

.review { border: 1px solid var(--line); margin-bottom: 26px; }
.review .line {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 11px 14px; border-bottom: 1px solid var(--line); font-size: 14px;
}
.review .line:last-child { border-bottom: none; }
.review .line .sku { font-family: var(--mono); font-size: 11px; color: var(--faint); }
.review .line .amt { font-family: var(--mono); font-size: 13px; white-space: nowrap; }
.review .total { display: flex; justify-content: space-between; padding: 13px 14px; border-top: 1px solid var(--ink); font-family: var(--mono); font-size: 15px; font-weight: 600; }

/* ---------- confirmation ---------- */

.done { max-width: 560px; margin: 0 auto; padding: 60px 0; text-align: left; }
.done h1 { font-size: 28px; font-weight: 500; margin: 0 0 12px; letter-spacing: -.02em; }
.done p { color: var(--muted); font-size: 15px; }
.done .actions { margin-top: 30px; display: flex; flex-wrap: wrap; gap: 12px; }
.wa {
  background: #111; color: #fff; border-color: #111;
}

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

.foot {
  border-top: 1px solid var(--line); margin-top: 50px; padding: 26px 0 60px;
  font-family: var(--mono); font-size: 11.5px; color: var(--faint);
  display: flex; flex-wrap: wrap; gap: 6px 20px; justify-content: space-between;
}
.foot a { color: var(--muted); }

.empty { padding: 80px 0; color: var(--muted); font-size: 15px; }

/* ES/EN and PEN/USD: one control, drawn one way. A single hairline box of
   equal-height segments with the chosen one inverted — whether the segment
   is an anchor (language reloads the page) or a button (currency repaints
   in place) nothing about the element's tag may show through: same box,
   same height, same type, baseline for baseline. */
.langs, .curs {
  display: inline-flex; align-items: stretch;
  border: 1px solid var(--line);
  font-family: var(--mono); font-size: 11px; letter-spacing: .05em;
}
.langs a, .curs button {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 40px; height: 28px; padding: 0 8px;
  background: none; border: 0; margin: 0; cursor: pointer;
  color: var(--muted); text-decoration: none; text-transform: uppercase;
  font: inherit; letter-spacing: inherit; line-height: 1;
}
.langs a + a, .curs button + button { border-left: 1px solid var(--line); }
.langs a[aria-current="true"], .curs button[aria-pressed="true"] {
  background: var(--ink); color: var(--ground);
}

/* ---------- print: the line sheet ---------- */

@media print {
  .pdfcover {
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; text-align: center; gap: 18px;
    height: 88vh; break-after: page;
  }
  .pdfcover-for {
    font-family: var(--mono); font-size: 12px; letter-spacing: .1em;
    text-transform: uppercase;
  }
  .pdfcover-line { font-family: var(--mono); font-size: 11px; color: var(--muted); }
  .product { break-inside: avoid; }
  .sheetcols { display: block; }
  .sheetrail, .wbreath { display: none; }
  @page { size: A4; margin: 14mm; }
  .topbar, .orderbar, .filters, .noprint, .foot,
  .pubbar, .pdpbar, .pubfoot { display: none !important; }
  /* flex fragments unreliably across print pages — a plain block prints */
  body { font-size: 10.5pt; padding: 0 !important; display: block; min-height: 0; }
  .wrap { max-width: none; padding: 0; }
  .product { break-inside: avoid; page-break-inside: avoid; padding: 10mm 0; grid-template-columns: 42mm 1fr; gap: 8mm; }
  .shots .strip { display: none; }
  .shots .lead { aspect-ratio: 4 / 5; }
  .sheetnote { display: block !important; }
  a { text-decoration: none; }
}
.sheetnote { display: none; }

/* ---------- wholesale, revised 2026-07-28 ---------- */

/* The on-screen wholesale sheet dropped its lead photograph, so its rows are
   one full-width column. linesheet.php still uses the two-column .product for
   PRINT, where a picture per product earns its space. */
.product.sheet-row { grid-template-columns: minmax(0, 1fr); }

.topright { display: flex; align-items: center; gap: 14px; }
.meta h2 a.plain { color: inherit; text-decoration: none; }
.meta h2 a.plain:hover { text-decoration: underline; text-underline-offset: 3px; }
.review .amt { font-family: var(--mono); font-size: 13px; white-space: nowrap; }

/* the swatch is the way into the photos now */
table.ways .shot {
  padding: 0; border: 1px solid var(--line); background: none; cursor: zoom-in;
  line-height: 0; flex: none;
}
table.ways .shot img { width: 44px; height: 44px; display: block; }
table.ways .shot:hover { border-color: var(--ink); }
table.ways .margin {
  font-family: var(--mono); font-size: 11.5px; color: var(--ink); font-weight: 500;
}

/* lightbox: every published photo of one product, swipeable */
.lightbox {
  position: fixed; inset: 0; z-index: 60; background: rgba(20, 20, 20, .94);
  display: flex; align-items: center; justify-content: center; gap: 8px; padding: 20px;
}
.lightbox[hidden] { display: none; }
.lb-stage { margin: 0; max-width: 100%; max-height: 100%; text-align: center; }
.lb-stage img {
  max-width: min(1100px, 92vw); max-height: 82vh; object-fit: contain; display: block;
  margin: 0 auto;
}
.lb-stage figcaption {
  color: #eee; font-family: var(--mono); font-size: 12px; padding-top: 12px;
  letter-spacing: .04em;
}
.lb-close, .lb-nav {
  background: none; border: none; color: #fff; cursor: pointer; line-height: 1;
  opacity: .75; transition: opacity 120ms ease;
}
.lb-close:hover, .lb-nav:hover { opacity: 1; }
.lb-close { position: absolute; top: 14px; right: 18px; font-size: 34px; padding: 8px 12px; }
.lb-nav { font-size: 46px; padding: 12px 16px; flex: none; }

/* order review: the case for the order, not a bill */
.review .line { align-items: center; gap: 14px; }
/* one dim, not two: the per-part rules at the review block own this state */
.review .line-what { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.review .line-name { font-size: 14.5px; }
.review .line-econ { font-family: var(--mono); font-size: 11.5px; color: var(--muted); }
.review .line-econ .margin { color: var(--ink); }

/* ---------- the public catalogue, photo-forward (2026-07-29) ---------- */

/* Rebuilt against rendered screenshots. The rules this block obeys, each one
   learned from a failure visible in the first cut's renders:

   · Photographs are never cover-cropped past 4:5 — a full-viewport crop of an
     uncontrolled photo is a zoom accident, not editorial.
   · No text sits on a photograph except the wordmark and the hero's name, and
     those are inked or whited per slide by measurement (pub_tone), not hope.
   · Photographs that sit NEXT to each other get white between them; captions
     live under photos in ink. mix-blend-mode is banned — it painted product
     names baby-blue over brown leather.

   The house rules do not change: white ground, near-black ink, 1px hairlines,
   square corners, no shadows, no decoration. What carries the page is the
   size of the photographs and the white around them. */

:root { --pubbar: 54px; --closure-offset: 82px; }

/* A dated service notice, not a promotion: full-width, high-contrast, and
   deliberately quiet. It lives on every customer-facing page—including the
   enquiry checkout—until this visitor dismisses this specific notice. */
.closure-notice {
  position: relative; z-index: 51;
  display: grid; grid-template-columns: 1fr auto; align-items: center;
  min-height: 82px; padding: 14px 18px 15px 48px;
  background: var(--ink); color: var(--ground); text-align: center;
}
.closure-notice[hidden] { display: none; }
.closure-notice-text { justify-self: center; }
.closure-notice-eyebrow {
  margin: 0 0 4px; font-family: var(--mono); font-size: 10px;
  line-height: 1.3; letter-spacing: .1em; text-transform: uppercase;
}
.closure-notice-copy {
  max-width: 76ch; margin: 0 auto; font-size: 13px; line-height: 1.45;
  letter-spacing: -.006em;
}
.closure-notice-close {
  width: 30px; height: 30px; padding: 0; border: 0;
  background: none; color: inherit; cursor: pointer;
  font: 300 25px/1 var(--sans); text-align: center;
}
.closure-notice-close:focus-visible { outline: 1px solid currentColor; outline-offset: 2px; }

@media (max-width: 480px) {
  :root { --closure-offset: 101px; }
  .closure-notice { min-height: 101px; padding: 14px 13px 15px 43px; }
  .closure-notice-copy { font-size: 12.5px; }
}

.pubbar {
  position: sticky; top: 0; z-index: 50;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  height: var(--pubbar); padding: 0 14px;
  background: var(--ground); color: var(--ink);
}
.pubbar .mark { grid-column: 2; line-height: 0; color: inherit; transition: opacity 160ms ease; }
/* while the big wordmark is on screen, the small one stands down */
.pubbar.nomark .mark { opacity: 0; pointer-events: none; }

/* Video mode (the home page with footage): the bar starts as a lone white
   burger floating on the video. When the video scrolls out, the white ground
   slides down BEHIND the controls — the items never move, they are revealed
   in place (Brian, 2026-07-29). The ground is a ::after layer so the slide is
   the background's, not the content's. */
.pubbar.floating {
  position: fixed; left: 0; right: 0; top: var(--closure-offset);
  background: none; border-bottom: none; color: #fff;
  transition: color 240ms ease, top 160ms ease;
}
.pubbar.floating::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--ground);
  transform: translateY(-101%);
  transition: transform 300ms ease;
}
.pubbar.floating .mark, .pubbar.floating .bagbtn {
  opacity: 0; pointer-events: none;
  transition: opacity 200ms ease;
}
.pubbar.floating.revealed { color: var(--ink); }
.pubbar.floating.revealed::after { transform: translateY(0); }
.pubbar.floating.revealed .mark,
.pubbar.floating.revealed .bagbtn { opacity: 1; pointer-events: auto; transition-delay: 120ms; }
/* Opening the drawer no longer summons the bar's ground (Brian, 2026-07-31:
   the ground drops ONLY when the film scrolls out) — the full-viewport scrim
   provides the contrast the old :has() rules existed for, and the bar sits
   dimmed beneath it like the rest of the page. */
/* the page under a fixed bar starts at the top — the video touches it */
.pubmain.underbar { margin-top: 0; }
@media (prefers-reduced-motion: reduce) {
  .pubbar.floating, .pubbar.floating::after,
  .pubbar.floating .mark, .pubbar.floating .bagbtn { transition: none; }
}

/* burger: three hairlines, the same weight as every other rule on the page */
.navbox { grid-column: 1; justify-self: start; }
.navbox > summary {
  list-style: none; cursor: pointer; padding: 12px 12px 12px 0; display: block;
}
.navbox > summary::-webkit-details-marker { display: none; }
.burger, .burger::before, .burger::after {
  display: block; width: 20px; height: 1px; background: currentColor; content: '';
}
.burger::before { transform: translateY(-6px); }
.burger::after { transform: translateY(5px); }
.navbox[open] .burger { background: none; }
.navbox[open] .burger::before { transform: translateY(1px) rotate(45deg); }
.navbox[open] .burger::after { transform: translateY(0) rotate(-45deg); }

/* A drawer, not a curtain: two-thirds of the screen, the page still visible
   (dimmed) beside it. The scrim is functional — tapping it closes.

   It opens the way the top bar does (Brian, 2026-07-31): the WORDS never
   move — they are already in place — and the white ground unfurls from the
   left to reveal them, then withdraws the same way on close. clip-path
   rather than a transform for exactly that reason: a sliding panel would
   carry the text with it, which is the thing the bar deliberately does not
   do.

   Driven by a CLASS the footer script toggles ('.animated' at setup, '.in'
   per open), not by <details> rendering: Gecko does not reliably start CSS
   animations on content that appears inside a freshly-opened <details>
   (found live 2026-07-31 — Firefox showed no animation at all), and a
   closing animation is impossible under native <details> anyway, which
   hides the panel the instant it closes. Class-driven transitions run
   identically in every engine, and the script holds the drawer open until
   the withdrawal finishes. Without JS the base state below never applies
   ('.animated' is script-added), so the drawer simply opens and closes
   instantly — the honest fallback. */
/* The scrim covers EVERYTHING that isn't the drawer — the top bar included
   (Brian, 2026-07-31): z 55 sits over the bar's 50, the panel over both.
   Closing is a tap anywhere on the dimmed page, bar included. */
.navscrim {
  position: fixed; inset: 0; z-index: 55;
  background: rgba(23, 17, 12, .32);
}
.navpanel {
  /* the full height of the viewport (Brian, 2026-07-31) — which buries the
     bar's ✕, so the panel carries its own top row */
  position: fixed; top: 0; bottom: 0; left: 0; z-index: 60;
  width: min(72vw, 400px);
  background: var(--ground); color: var(--ink);
  border-right: 1px solid var(--line);
  padding: 0 20px 28px; overflow-y: auto;
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
}
.navtop {
  position: sticky; top: 0; z-index: 1; background: var(--ground);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: calc(100% + 40px); margin: 0 -20px 16px; padding: 0 14px 0 0;
  min-height: var(--pubbar); flex: none;
}
/* The close is DRAWN, not typed: the same two 20px hairlines the burger
   crosses into, at the exact spot where the bar's burger sits — so when the
   panel's ground unfurls over the bar, the reader sees one X, one weight,
   never moving. (The typed × was a fatter glyph landing on top of the
   hairline X behind it — two mismatched X's in the same corner.) */
.navclose {
  position: relative; display: block; width: 48px; height: var(--pubbar);
  flex: none; color: var(--ink);
  /* if the toggle row ever wraps to two lines, the X stays pinned where
     the bar's burger is instead of drifting to the taller row's middle */
  align-self: flex-start;
}
/* the narrowest phones: tighter segments so the toggle row keeps one line */
@media (max-width: 360px) {
  .langs a, .curs button { min-width: 34px; padding: 0 6px; }
}
.navclose::before, .navclose::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 20px; height: 1px; margin: .5px 0 0 -10px;
  background: currentColor;
}
.navclose::before { transform: rotate(45deg); }
.navclose::after { transform: rotate(-45deg); }
.navbottom {
  margin-top: auto; padding-top: 34px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
}
.navbottom a {
  display: block; padding: 6px 0; font-size: 15px;
  text-decoration: none; color: var(--ink);
}
.navnewsletter {
  margin: 0 0 16px; padding: 9px 11px; border: 1px dashed currentColor;
  border-radius: 0; background: transparent; color: var(--ink); cursor: pointer;
  font-family: var(--mono); font-size: 10px; letter-spacing: .08em; line-height: 1.2;
  text-transform: uppercase;
}
.navnewsletter:hover { background: var(--ink); color: var(--ground); }
.navnewsletter[hidden] { display: none; }
.navnewsletter:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.navbox.animated .navpanel {
  clip-path: inset(0 100% 0 0);
  transition: clip-path 340ms cubic-bezier(.22, .61, .21, 1);
}
.navbox.animated .navscrim {
  opacity: 0;
  transition: opacity 340ms ease;
}
.navbox.animated.in .navpanel { clip-path: inset(0 0 0 0); }
.navbox.animated.in .navscrim { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .navbox.animated .navpanel, .navbox.animated .navscrim { transition: none; }
}
.navtags { display: flex; flex-wrap: wrap; gap: 6px; }
.navtag {
  border: 1px solid var(--line); padding: 6px 10px; text-decoration: none;
  font-size: 12.5px; color: var(--muted);
}
.navtag:hover { border-color: var(--ink); color: var(--ink); }
.togglerow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.navhead {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); margin: 26px 0 8px;
}
.navitem {
  display: block; padding: 8px 0; font-size: 22px; letter-spacing: -.01em;
  text-decoration: none; color: var(--ink);
}

.bagbtn { grid-column: 3; justify-self: end; margin: 0; }
.bagbtn[hidden] { display: none; }
.bagbtn button {
  background: none; border: none; padding: 10px 0; cursor: pointer; color: inherit;
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase;
}

/* the main flexes so the footer lands at the window's foot on short pages */
.pubmain { flex: 1 0 auto; padding-bottom: 40px; }
.pubmain .empty, .pubmain .sheet, .pubmain .done { padding-left: 20px; padding-right: 20px; }

/* ---------- the video hero ---------- */

/* Full width, touching the top, with the next photographs peeking below —
   an opening shot, not a wall. It links nowhere and says nothing except the
   mark, plain white and dead centre: Brian grades the footage to carry it. */
.vhero { position: relative; line-height: 0; }
.vhero video {
  /* Taller since the 1080x1600 cut (2026-07-29): Cleo wanted the film to
     carry further down the page. 160vw against a 1.48 master crops a hair
     off the sides — the mark is centred, so it survives — and still leaves
     a clear peek of the first photograph underneath, which is the whole
     point of stopping short of the fold. */
  width: 100%; height: min(86svh, 160vw); object-fit: cover; display: block;
  background: #1E160E;   /* the first frame's stand-in, leather-dark */
}
.vhero .heromark {
  position: absolute; inset: 0; top: 0;
  display: flex; align-items: center; justify-content: center;
  color: #fff; pointer-events: none;
}
.vhero .heromark svg { width: min(46vw, 240px); height: auto; }

/* ---------- the hero reel ---------- */

/* One photograph at a time, most of the screen but not all of it: 4:5 capped
   by 74svh, so a portrait phone shot is barely cropped and the feed peeks in
   below to say there is more. The wordmark sits ON the reel, large; the name
   and position sit UNDER it on white, where they cannot be lost. */
.hero { position: relative; }
.heroreel {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.heroreel::-webkit-scrollbar { display: none; }
.heroslide { flex: 0 0 100%; scroll-snap-align: start; line-height: 0; }
.heroslide img {
  width: 100%; height: min(74svh, 125vw); object-fit: cover; object-position: center 40%;
}

.heromark {
  position: absolute; top: clamp(14px, 4.5svh, 44px); left: 0; right: 0;
  display: flex; justify-content: center; pointer-events: none;
}
.heromark svg { width: min(46vw, 240px); height: auto; }
.hero.tone-dark .heromark { color: #fff; }
.hero.tone-light .heromark { color: var(--ink); }

.herostrip {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 12px 20px 0; background: var(--ground);
}
.heroname { font-size: 15px; font-weight: 500; letter-spacing: -.01em; }
.herosegs { display: flex; align-items: center; }
/* each segment is a real button — a direct jump to its slide — with a hit
   area far larger than the 2px line it draws */
.herosegs button {
  position: relative; width: 24px; height: 18px; padding: 0;
  background: none; border: none; cursor: pointer;
}
.herosegs button::after {
  content: ''; position: absolute; left: 3px; right: 3px; top: 8px; height: 2px;
  background: var(--ink); opacity: .22;
}
.herosegs button.on::after { opacity: 1; }
.herosegs button:hover::after { opacity: .55; }
.herosegs button.on:hover::after { opacity: 1; }

/* the arrows exist for machines without a thumb — see the desktop block */
.heroarr { display: none; }

.pubhead { padding: 30px 20px 6px; max-width: 62ch; }
.pubhead h1 { margin: 0 0 6px; font-size: 26px; font-weight: 500; letter-spacing: -.015em; }
.pubhead p { margin: 0; color: var(--muted); font-size: 15px; }
.pubhead a { font-family: var(--mono); font-size: 12px; color: var(--muted); }

/* ---------- the feed ---------- */

/* The window display: photographs only — no captions, no prices — each one
   with white around it (never edge to edge), in an irregular rhythm of
   full-width and paired tiles set server-side. Capped at twenty; the whole
   range lives on the tienda page. */
.feed {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 14px 12px; padding: 26px 12px 10px;
}
.tile { display: block; text-decoration: none; color: var(--ink); min-width: 0; }
.tile .ph { display: block; line-height: 0; }
.tile img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.tile.g { grid-column: 1 / -1; }

/* Anything the shared observer marks .lazy fades and rises the first time it
   enters the viewport — the home feed's arrival, now on every gallery
   (Brian, 2026-07-31). The class is added BY the observer's setup, so
   without JS nothing is ever hidden. */
.lazy { opacity: 0; transform: translateY(18px); }
.lazy.in { opacity: 1; transform: none; transition: opacity 480ms ease, transform 480ms ease; }
@media (prefers-reduced-motion: reduce) {
  .lazy { opacity: 1; transform: none; }
}

.seemore { display: flex; justify-content: center; padding: 26px 12px 6px; }

/* ---------- la tienda: every colourway on its own tile ---------- */

.shopgrid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 30px 12px; padding: 10px 12px 10px;
}
.shoptile { min-width: 0; }
.shoptile .ph { display: block; line-height: 0; }
.shoptile .ph img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.trow { display: flex; align-items: flex-start; gap: 8px; padding-top: 8px; }
.tinfo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; text-decoration: none; color: var(--ink); }
.tname { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tcolor { font-size: 12px; color: var(--muted); }
.tprice { font-size: 12.5px; padding-top: 2px; }
/* The other colours, right-aligned to the photo's edge: flat chips, each one
   the colour MEASURED off that colourway's own photograph (pub_swatch) — so
   they are still honest about the leather, without a thumbnail's worth of
   detail fighting the name beside it. The hairline keeps a cream chip from
   dissolving into the white ground. A colour that would not measure keeps its
   little photograph (.sw.ph). */
.tswatches { display: flex; gap: 5px; flex: none; padding-top: 2px; }
.tswatches .sw {
  display: block; width: 15px; height: 15px; border-radius: 50%;
  border: 1px solid var(--line); line-height: 0;
}
.tswatches .sw.ph { border-radius: 50%; overflow: hidden; }
.tswatches .sw img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tswatches .sw:hover { border-color: var(--ink); }

/* ---------- what else to look at ---------- */

/* Two whole tiles and the edge of a third: the sliver IS the affordance, so
   it is a width, not an arrow. Snap so a flick lands square. */
.pdprel { padding: 26px 0 4px; }
.relrow {
  display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x proximity;
  padding: 0 20px 4px; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  /* without this the snap aligns tiles to the SCROLLPORT edge and the row
     opens already scrolled past its own left padding — the first tile
     touching the screen edge while every other line on the page is inset */
  scroll-padding-left: 20px;
}
.relrow::-webkit-scrollbar { display: none; }
.reltile { flex: 0 0 41%; min-width: 0; scroll-snap-align: start; }
.reltile .ph { display: block; line-height: 0; }
.reltile .ph img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.reltile .trow { gap: 6px; }
.reltile .tname { font-size: 13px; }

/* ---------- one product, publicly ---------- */

.pdp { padding-bottom: 8px; }

.pdphead { padding: 24px 20px 16px; }
.pdphead h1 { margin: 0; font-size: 26px; font-weight: 500; letter-spacing: -.015em; }
.pdpcolor { font-size: 12px; color: var(--muted); margin-top: 5px; letter-spacing: .04em; }

.pdpshots { display: flex; flex-direction: column; gap: 10px; }
.pdpshots img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }

.pdpmeta { padding: 22px 20px 0; max-width: 62ch; }
.pdpmeta .desc { margin: 0; font-size: 15.5px; line-height: 1.6; }
.pdptags { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 16px; }
.pdptags a { font-size: 13px; color: var(--muted); text-decoration: none; }
.pdptags a::before { content: '#'; color: var(--faint); }
.pdptags a:hover { color: var(--ink); }
.pdpsku { font-size: 11px; color: var(--faint); margin-top: 16px; letter-spacing: .08em; }

/* other colours: thumbnail plus the colour's name, at the foot of the page */
.pdpways { padding: 30px 0 0; }
.pdpwayshead {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); padding: 0 20px 10px;
}
.waystrip { display: flex; gap: 10px; overflow-x: auto; padding: 0 20px 4px; scrollbar-width: none; }
.waystrip::-webkit-scrollbar { display: none; }
.way { flex: 0 0 auto; width: 78px; text-decoration: none; color: var(--ink); }
.way img, .waynophoto {
  display: block; width: 78px; height: 98px; object-fit: cover;
  border: 1px solid var(--line); background: #f4f4f4;
}
.way.on img, .way.on .waynophoto { border-color: var(--ink); }
.wayname {
  display: block; margin-top: 6px; font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.way.on .wayname { color: var(--ink); }

/* the name, the price, and the way to ask — always on screen */
.pdpbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  min-height: var(--bar); display: flex; align-items: center; gap: 14px;
  padding: 8px 20px calc(8px + env(safe-area-inset-bottom) / 2);
  background: var(--ground); border-top: 1px solid var(--line);
}
.pdpwhat { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.pdpbarname {
  font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pdpprice { font-size: 14px; }
.pdpbar .btn { flex: none; }
.pdpbar .btn[disabled] { opacity: .4; cursor: default; }
.pdpbar .btn.inbag { background: var(--ground); color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }

/* The handle is a TRUE footer now (Brian, 2026-08-01: the fixed corner chip
   floated over content on phones) — the last thing in the flow, seen only
   when the reader reaches the end of the page, never riding above it. The
   body is a full-height column and the main flexes (see body / .pubmain),
   so a page with little on it still ends at the viewport's foot. */
.pubfoot {
  border-top: 1px solid var(--line);
  display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 6px 20px;
  padding: 18px 20px calc(20px + env(safe-area-inset-bottom));
  font-family: var(--mono); font-size: 11.5px;
}
.pubfoot a { color: var(--muted); text-decoration: none; }
.pubfoot a:hover { color: var(--ink); }
/* under the product page's fixed enquiry bar the footer still has to
   surface: clear the bar so the page's last line is readable above it */
.pubmain.haspdp + .pubfoot {
  padding-bottom: calc(var(--bar) + 20px + env(safe-area-inset-bottom));
}

@media (min-width: 900px) {
  /* Wide screens do not full-bleed the hero: forcing a portrait photograph
     into a landscape letterbox is the same zoom accident the phone layout
     was cured of. The photo keeps 4:5, centered on the white ground like a
     lookbook plate, with the wordmark over the plate. */
  .heroslide { display: flex; justify-content: center; background: var(--ground); }
  .heroslide img { width: auto; height: min(80vh, 700px); aspect-ratio: 4 / 5; }
  .heromark svg { width: min(20vw, 250px); }
  .herostrip { justify-content: center; gap: 26px; }
  /* a mouse can't swipe and the scrollbar is hidden: naked chevrons in the
     white margins beside the plate, same register as the lightbox's */
  .heroarr {
    display: block; position: absolute; top: 50%; transform: translateY(-50%);
    z-index: 5; background: none; border: none; cursor: pointer;
    font-size: 40px; line-height: 1; padding: 10px 18px; color: var(--ink);
    opacity: .45; transition: opacity 120ms ease;
  }
  .heroarr:hover, .heroarr:focus-visible { opacity: 1; }
  /* just off the plate's shoulders, not the viewport's — the plate is 4:5 of
     min(80vh, 700px) tall, so its half-width is min(32vh, 280px) */
  .heroarr.prev { left: max(16px, calc(50% - min(32vh, 280px) - 74px)); }
  .heroarr.next { right: max(16px, calc(50% - min(32vh, 280px) - 74px)); }
  .herostrip, .pubhead { padding-left: 40px; padding-right: 40px; }
  /* uniform 3-up: a spanning tile at 4:5 towers over its row and leaves a
     hole beside it — the full-width emphasis is a phone rhythm */
  .feed { grid-template-columns: repeat(3, 1fr); gap: 20px 16px; padding: 34px 40px 10px; }
  .tile.g { grid-column: auto; }
  .shopgrid { grid-template-columns: repeat(3, 1fr); gap: 40px 16px; padding: 10px 40px; }
  .relrow { padding-left: 40px; padding-right: 40px; scroll-padding-left: 40px; }
  .reltile { flex: 0 0 23%; }
  /* Height-driven, not width-driven (Brian, 2026-07-31: "much taller, maybe
     80% of the viewport height"). The old min(86vh, 52vw) tied the film's
     height to the window's WIDTH, so a half-screen browser — 960 wide beside
     a terminal — collapsed it to 50vh while a maximised one got 83vh. The
     film is now 80% of the viewport on every desktop window, and a taller
     box crops the portrait master LESS, not more. */
  .vhero video { height: 80vh; }
  .vhero .heromark svg { width: min(20vw, 250px); }
  .seemore { padding: 34px 40px 6px; }
  .pdphead, .pdpmeta, .pdpwayshead, .waystrip { padding-left: 40px; padding-right: 40px; }
  .pdpshots { display: grid; grid-template-columns: 1fr 1fr; padding: 0 40px; }
  .pdpbar { padding-left: 40px; padding-right: 40px; }
  .pubfoot { padding-left: 40px; padding-right: 40px; }
}

/* ---------- the enquiry review: edit in place, send two ways ---------- */

.review .line { display: flex; align-items: center; gap: 12px; padding: 12px 0; }
.review .line .qty { flex: none; }
.review .line.dropped .line-what,
.review .line.dropped .amt { opacity: .4; }
.sendrow { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.sendrow .btn { flex: 1; min-width: 150px; text-align: center; }
.btn.wa { background: var(--ink); }

/* ---------- narrow screens ---------- */

@media (max-width: 720px) {
  .product { grid-template-columns: 1fr; gap: 18px; padding: 32px 0; }
  .intro { padding: 30px 0 24px; }
  .orderbar { padding-left: 16px; padding-right: 16px; }
  .wrap { padding: 0 16px; }
  /* the suggested price and the margin are the reason a shop says yes —
     they stay on the phone, where most of this is actually read */
  .lb-nav { font-size: 34px; padding: 8px; }
  .review .line { flex-wrap: wrap; }
}

/* ---- el taller: the maker's page (briefs/voice.md, layer 2) ----
   The lookbook's register brought to the web: white ground, one column,
   letterspaced kickers, photographs as framed plates with mono captions.
   Nothing decorative — the photographs are the argument. */
.taller-page { max-width: 680px; margin: 0 auto; padding: 34px 20px 30px; }
.taller-page h1 {
  font-size: 22px; font-weight: 500; letter-spacing: .01em; margin: 0 0 6px;
}
.taller-page .kicker {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .18em;
  color: var(--muted); margin: 38px 0 16px;
}
.taller-page p {
  font-size: 15.5px; line-height: 1.65; max-width: 62ch; margin: 0 0 1em;
}
.taller-page .plate { margin: 30px 0 6px; max-width: 540px; }
.taller-page .plate img { width: 100%; height: auto; display: block; }
.taller-page .plate figcaption {
  font-family: var(--mono); font-size: 11px; letter-spacing: .08em;
  color: var(--muted); margin-top: 8px;
}
.tallerclose { margin-top: 40px; padding-top: 22px; border-top: 1px solid var(--line); }
.tallerclose .closeline { color: var(--muted); margin-bottom: 16px; }

/* "write to us" wherever a page invites it (2026-08-02). One rule for all of
   them — El taller, the two confirmations, the wholesale done page — so the
   invitation reads the same weight everywhere instead of borrowing whatever
   the surrounding block happened to be. Quiet by default; the address is the
   only underlined thing in it, because the address is the point. */
.reachline {
  margin: 18px 0 0; font-size: 14px; color: var(--muted); max-width: 56ch;
}
.reachline a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.tallerclose .reachline { margin-top: 22px; }

/* ---- proof tokens on the product page (briefs/voice.md layer 1) ---- */
.pdpline0 { font-size: 15.5px; color: var(--ink); margin: 10px 0 0; max-width: 52ch; }
.pdpfacts {
  display: grid; grid-template-columns: max-content 1fr; gap: 6px 18px;
  margin: 20px 0 0; font-size: 13px;
}
.pdpfacts dt { font-family: var(--mono); font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); padding-top: 2px; }
.pdpfacts dd { margin: 0; }
.pdpstd { font-size: 13px; color: var(--muted); margin: 18px 0 0; max-width: 56ch; }
.pdpprov { font-size: 13px; margin: 10px 0 0; }
.pdpprov a { text-decoration: underline; text-underline-offset: 2px; }

/* ---- the product-page lightbox (desktop): bar pinned to the WINDOW ----
   Controls that sit under the photograph move with each photo's height and
   become unusable across clicks (Brian, 2026-07-31, same fix as the admin
   viewer) — so the stage gets everything above a fixed-height bottom bar,
   and the buttons never move. */
@media (min-width: 900px) {
  .pdpshots img { cursor: zoom-in; }
}
.pdlb .lb-stage { position: absolute; inset: 0 0 74px; display: flex; align-items: center; justify-content: center; padding: 24px; }
.pdlb .lb-stage img { max-width: 92vw; max-height: 100%; object-fit: contain; }
.pdlb .lb-bar {
  position: absolute; left: 0; right: 0; bottom: 0; height: 74px;
  display: flex; align-items: center; justify-content: center; gap: 22px;
  color: #eee; font-family: var(--mono); font-size: 12px; letter-spacing: .04em;
}
.pdlb .lb-nav { font-size: 34px; padding: 8px 18px; }

/* ---- dónde comprar: the stockists, grouped by city ---- */
.stockists { max-width: 620px; margin: 0 auto; padding: 40px 20px 60px; }
.stockists h1 { font-size: 26px; font-weight: 500; margin: 0 0 6px; letter-spacing: -.02em; }
.stlede { color: var(--muted); margin: 0 0 10px; font-size: 15px; }
.stcity {
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); margin: 28px 0 6px;
}
.stlist { list-style: none; margin: 0; padding: 0; }
.stlist li { padding: 7px 0; font-size: 17px; }
.stlist a { text-decoration: underline; text-underline-offset: 3px; }
.stlist .staddr { display: block; font-family: var(--mono); font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.stlist .staddr a { text-underline-offset: 2px; }

/* the wholesale door, rendered at last (the page's header always called
   itself quiet wholesale marketing — now it says so) */
.stdoor { margin-top: 44px; padding-top: 18px; border-top: 1px solid var(--line); }
.stdoor p { margin: 0 0 6px; font-size: 15px; }
.stdoor .stback { font-family: var(--mono); font-size: 12px; }
.stdoor a { text-underline-offset: 3px; }

/* ---- policies ---- */
.policies { max-width: 620px; margin: 0 auto; padding: 40px 20px 60px; }
.policies h1 { font-size: 26px; font-weight: 500; margin: 0 0 6px; letter-spacing: -.02em; }
.polhead {
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); margin: 30px 0 8px;
}
.policies p { margin: 0 0 12px; font-size: 15px; color: #333; max-width: 56ch; }
.polask { margin-top: 34px; }
.polask a { text-decoration: underline; text-underline-offset: 3px; }

/* ---- the stockists map: real tiles, our own engine ----
   OSM data on CARTO's light basemap tiles, driven by ~300 lines of our own
   JS in the page (no library; the only third party is the tile CDN itself,
   credited bottom-right as the licence requires — tile.openstreetmap.org
   itself proved unreachable from Peru, 2026-07-31, hence the CDN). The
   light style is already quiet enough for the house frame, so the tiles
   ship UNFILTERED and geography finally reads: ocean, borders, streets.
   Pins are ink dots; a shop with GPS is a hollow ring at its own door; a
   tap names the shops. Full-bleed left to right (Brian, 2026-07-31); the
   map wakes on first tap so a scrolling thumb is never trapped. */
.stmap {
  position: relative; height: clamp(340px, 62vh, 560px);
  width: 100vw; margin: 18px calc(50% - 50vw) 10px;
  border-block: 1px solid var(--line);
  background: #f2f2f2; overflow: hidden;
  touch-action: pan-y; cursor: grab;
}
.stmap.live { touch-action: none; }
.stmap.dragging { cursor: grabbing; }
.stmap:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.stmap img { max-width: none; }
.stmap-world { position: absolute; left: 0; top: 0; will-change: transform; }
/* z-index:0 contains the per-tile z ladder (old zooms under new,
   up to 500) so it can never paint over the pins layer above */
.stmap-tiles { position: absolute; left: 0; top: 0; z-index: 0; }
.stmap-tiles img { position: absolute; user-select: none; pointer-events: none; }
.stmap-pins { position: absolute; left: 0; top: 0; z-index: 1; }
.stpin {
  position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px;
  background: var(--ink); border: 2px solid var(--ground); border-radius: 50%;
  box-sizing: content-box; cursor: pointer; padding: 0;
}
.stpin::after { content: ''; position: absolute; inset: -10px; }
/* a crowd of shops, as one dot wearing its number — tapping it zooms in
   until they stand apart (the spider legs it replaces read as clutter) */
.stcluster {
  position: absolute; width: 28px; height: 28px; margin: -14px 0 0 -14px;
  border-radius: 50%; border: 2px solid var(--ground); background: var(--ink);
  color: var(--ground); font-family: var(--mono); font-size: 12px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  box-sizing: border-box; cursor: zoom-in; padding: 0;
}

/* a shop's own door: hollow ring, so street pins and city dots read as
   different kinds of true */
.stpin--shop { background: var(--ground); border: 2px solid var(--ink); width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; }
.stpop {
  position: absolute; transform: translate(-50%, -100%); margin-top: -16px;
  background: var(--ground); border: 1px solid var(--ink);
  padding: 10px 12px; min-width: 150px; max-width: 230px;
  font-size: 13.5px; line-height: 1.5; z-index: 2;
}
/* a pin near the frame's top opens its card downward instead of clipping */
.stpop.below { transform: translate(-50%, 0); margin-top: 16px; }
.stpop .city {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 4px;
}
.stpop ul { list-style: none; margin: 0; padding: 0; }
.stpop a { text-decoration: underline; text-underline-offset: 3px; }
.stpop .addr { display: block; font-family: var(--mono); font-size: 10.5px; color: var(--muted); margin-top: 2px; }
.stmap-zoom {
  position: absolute; top: 10px; right: 10px; z-index: 6;
  display: flex; flex-direction: column;
  background: var(--ground); border: 1px solid var(--ink);
}
.stmap-zoom button {
  width: 36px; height: 36px; border: 0; background: none; cursor: pointer;
  font-family: var(--mono); font-size: 17px; color: var(--ink); line-height: 1;
  padding: 0;
}
.stmap-zoom button + button { border-top: 1px solid var(--line); }
.stmap-credit {
  position: absolute; right: 0; bottom: 0; z-index: 6;
  background: var(--ground); padding: 3px 6px;
  font-family: var(--mono); font-size: 10px; color: var(--muted);
}
.stmap-credit a { color: inherit; }
.stmap-wake {
  position: absolute; inset: 0; z-index: 5; width: 100%;
  display: flex; align-items: flex-end; justify-content: center;
  padding: 0 0 14px; margin: 0; background: none; border: 0; cursor: pointer;
}
.stmap-wake span {
  background: var(--ground); border: 1px solid var(--line);
  font-family: var(--mono); font-size: 11px; letter-spacing: .04em;
  color: var(--muted); padding: 6px 10px;
}

/* the shop's record shown at checkout, asking to be confirmed */
.shopfacts { margin: 26px 0 8px; }
.shopfacts-head {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
}
.shopfacts-note { margin: 6px 0 0; font-size: 13px; color: var(--muted); line-height: 1.5; }

/* Newsletter welcome: a quiet sheet pulled from the edge of the page. */
.nl-scrim { position: fixed; inset: 0; z-index: 80; background: rgba(20,18,15,.28); opacity: 0; transition: opacity .3s ease; }
.nl-scrim.open { opacity: 1; }
.nl-panel {
  position: fixed; z-index: 81; right: 24px; bottom: 24px; width: min(420px, calc(100vw - 48px));
  background: var(--ground); color: var(--ink); border: 1px solid var(--ink);
  padding: 42px 38px 34px; box-shadow: 0 18px 60px rgba(20,18,15,.18);
  transform: translateY(20px); opacity: 0; transition: transform .3s ease, opacity .3s ease;
}
.nl-panel.open { transform: none; opacity: 1; }
.nl-panel h2 { margin: 4px 0 14px; font-size: clamp(30px, 4vw, 46px); line-height: .98; letter-spacing: -.035em; }
.nl-eyebrow { margin: 0; font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.nl-copy { max-width: 35em; margin: 0 0 24px; line-height: 1.55; }
.nl-close { position: absolute; top: 12px; right: 14px; border: 0; background: none; color: inherit; font-size: 26px; line-height: 1; cursor: pointer; }
.nl-panel form label { display: block; margin: 0 0 12px; font-family: var(--mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase; }
.nl-panel form input { display: block; width: 100%; box-sizing: border-box; margin-top: 5px; padding: 11px 0 8px; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; background: transparent; color: inherit; font: inherit; font-size: 16px; text-transform: none; letter-spacing: 0; }
.nl-panel form input:focus { outline: 0; border-color: var(--ink); }
.nl-panel form .btn { width: 100%; margin-top: 8px; }
.nl-consent, .nl-error { margin: 12px 0 0; font-size: 11px; line-height: 1.45; color: var(--muted); }
.nl-error { color: var(--ink); }
.nl-honey { position: absolute !important; left: -9999px !important; }
.nl-code { width: 100%; margin: 14px 0 8px; padding: 18px; border: 1px dashed var(--ink); background: transparent; color: inherit; cursor: copy; text-align: left; }
.nl-code strong { display: block; font-family: var(--mono); font-size: 25px; letter-spacing: .09em; }
.nl-code span { display: block; margin-top: 5px; font-size: 11px; color: var(--muted); }
.nl-close:focus-visible, .nl-code:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
@media (max-width: 600px) {
  .nl-panel { right: 0; bottom: 0; width: 100%; padding: 38px 24px calc(24px + env(safe-area-inset-bottom)); border-width: 1px 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  .nl-panel, .nl-scrim { transition: none; }
}

.newsletter-optin { display: flex; gap: 10px; align-items: flex-start; margin: 24px 0 16px; font-size: 13px; line-height: 1.45; cursor: pointer; }
.newsletter-optin input { width: 16px; height: 16px; flex: 0 0 auto; margin: 2px 0 0; accent-color: var(--ink); }
.welcome-discount { position: relative; margin: 16px 0 24px; padding: 18px; border: 1px dashed var(--ink); }
.welcome-discount > div:first-child strong, .welcome-discount > div:first-child span { display: block; }
.welcome-discount > div:first-child strong { font-size: 14px; }
.welcome-discount > div:first-child span { margin-top: 3px; font-family: var(--mono); font-size: 10px; letter-spacing: .05em; color: var(--muted); }
.welcome-discount > button { position: absolute; top: 18px; right: 18px; border: 0; border-bottom: 1px solid currentColor; padding: 0; background: none; color: var(--muted); font-size: 11px; cursor: pointer; }
.welcome-discount dl { margin: 18px 0 0; }
.welcome-discount dl div { display: flex; justify-content: space-between; gap: 20px; margin-top: 7px; }
.welcome-discount dt, .welcome-discount dd { margin: 0; font-size: 13px; }
.welcome-discount .offer-final { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); font-weight: 600; }
