/* ============================================================
   CARTEL MASKS — storefront styles
   Brand: red #ff0000 / black / white, Oswald + Open Sans
   Hand-coded, no framework. Owned outright.
   ============================================================ */

/* ---------- Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--ink);

  /* The sello pattern is the paper this whole store is printed on.
     Two crests — one masked, one bare — on an even half-drop: columns offset by half a
     step, six neighbours, all the same distance away. One cached SVG, tiled forever.

     Scale is driven from HERE, never from inside the file. The tile is 53.7 × 62 units
     and it is NOT square, so this needs both numbers — pass it one and the crests go oval.
     128 / 53.7 = 2.38px per unit, which puts a crest on screen at ~67px.

     Crest size and gap are SEPARATE dials, and this is only the first one. It scales the
     whole tile, so it moves the crest and the air around it together. The air on its own
     lives in the tile's lattice (the pitches inside the SVG). Wanting "tighter" almost
     never means touching this number — it means closing the lattice and leaving this
     alone, which is what keeps the crest the size you already signed off on. */
  background: var(--black) var(--sello);
  background-size: 128px 148px;

  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { font-family: "Oswald", "Arial Narrow", sans-serif; font-weight: 700; margin: 0 0 .5em; line-height: 1.1; text-transform: uppercase; letter-spacing: .01em; }
button { font-family: inherit; cursor: pointer; }

:root {
  --red: #ff0000;
  --red-dark: #cc0000;
  --black: #000000;
  --gold: #d4af37;

  /* The site used to be a white page wearing a black hat. It is now black all the
     way down, so --ink is the text ON black and --paper is the white card. */
  --ink: #ffffff;
  --paper: #ffffff;
  --ink-on-paper: #111;
  --muted: #8f8a8c;           /* warm grey, biased off the sello's own #414042 */
  --line: #232326;            /* hairline that reads on black, not the old #e6e6e6 */
  --line-on-paper: #e6e6e6;

  --sello: url("/images/brand/sello-pattern.svg");

  --maxw: 1200px;
}

/* There is ONE sheet, and every page gets it. There used to be a second, quieter tile here for the
   pages you actually read on — the cart, the card form, the policies, the tour — on the theory that
   texture behind a paragraph should whisper. It shipped at a different size AND a different ink from
   the shop's, which meant the site quietly ran two patterns and the seam showed the moment anyone
   compared two pages. One pattern, one darkness, one size, top to bottom. If a page ever reads too
   busy, take it out of the INK inside the tile — do not fork the tile again. */

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }
.center { text-align: center; }
.sr-only { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); border:0; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block; border: 2px solid var(--red); background: var(--red); color: #fff;
  font-family: "Oswald", sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
  padding: 13px 28px; font-size: 15px; transition: background .15s, color .15s; border-radius: 2px;
}
.btn:hover { background: #fff; color: var(--red); }
.btn--ghost { background: transparent; color: var(--red); }
.btn--ghost:hover { background: var(--red); color: #fff; }
.btn--block { display: block; width: 100%; text-align: center; }
.btn--lg { padding: 16px 40px; font-size: 17px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* ---------- Header ---------- */
/* Flat black, no pattern. The bar used to carry the sello louder than the page did, on the theory
   that chrome can take more texture than a paragraph can. It reads better plain: the lockup is
   itself a busy piece of artwork, and it was competing with the tile behind it for the same eye.
   Solid black also means it stays properly opaque while the page scrolls under it — this bar is
   sticky, so a transparent background here would let the page smear through it. */
.site-header {
  position: sticky; top: 0; z-index: 50; color: #fff;
  background: #000;
  border-bottom: 1px solid var(--line);
}
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; height: 70px; gap: 16px; max-width: 1400px; padding: 0 28px; }
.brand { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.brand img { height: 46px; width: auto; display: block; }
.brand .brand-txt { font-family: "Oswald", sans-serif; font-weight: 700; font-size: 24px; color: #fff; text-transform: uppercase; letter-spacing: .02em; }
.brand .brand-txt b { color: var(--red); }
.main-nav { display: flex; gap: 22px; align-items: center; margin-left: auto; }
.main-nav a { font-family: "Open Sans", sans-serif; font-weight: 700; text-transform: none; font-size: 16px; letter-spacing: 0; color: #fff; padding: 6px 0; }
.main-nav a:hover, .main-nav a.active { color: var(--red); }
.cart-btn { position: relative; background: none; border: 0; color: #fff; display: flex; align-items: center; padding: 4px; }
/* The paletero cart, painted as a mask rather than drawn inline: the SVG supplies the
   shape, `currentColor` supplies the colour. That buys the hover-to-red the old inline
   path had, while keeping the artwork in one cached file instead of on every page.
   It's also the clean vector — the icon that shipped before was a mushy auto-trace. */
.cart-btn .cart-ico {
  display: block; width: 34px; height: 34px; background: currentColor;
  -webkit-mask: url("/images/brand/cart-paletas.svg") center / contain no-repeat;
          mask: url("/images/brand/cart-paletas.svg") center / contain no-repeat;
}
.cart-btn:hover { color: var(--red); }
.cart-btn .count {
  position: absolute; top: -6px; right: -9px;
  min-width: 18px; height: 18px; padding: 0 4px; border-radius: 999px; background: var(--red); color: #fff;
  font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; font-family: "Open Sans", sans-serif;
}
.nav-toggle { display: none; background: none; border: 0; color: #fff; font-size: 26px; line-height: 1; }

/* ---------- Hero ---------- */
/* Transparent, not black: the body's pattern is already behind this, and painting
   a flat #000 over it would punch a dead rectangle in the middle of the page. */
.hero { background: transparent; color: #fff; text-align: center; padding: 26px 20px 44px; }
.hero .hero-logo { max-width: 1360px; width: 96%; margin: 8px auto 20px; }
.hero h1 { font-family: "Open Sans", sans-serif; font-weight: 700; text-transform: none; font-size: clamp(42px, 7.6vw, 92px); color: #fff; margin: 0 0 .12em; letter-spacing: .005em; line-height: 1; }
.hero p { max-width: 780px; margin: 0 auto; color: #fff; font-size: 16px; font-weight: 700; }
.hero .btn { margin-top: 26px; }

/* Masthead hero (the shop page head). The vignette is the load-bearing part — an ellipse of
   near-black over the body's own sello pattern, fading to nothing at the edges, so the tiles
   stay alive in the corners and go quiet in the middle where the crest and the type sit.
   It's an ::after overlay, so it must not eat clicks: pointer-events none.

   Layer order in this section, bottom to top:
     body sello pattern  ->  ::after vignette (0)  ->  ::before type band (1)  ->  .wrap (2)

   The type band MUST out-rank the vignette. Put it underneath and the vignette — which is at
   its darkest dead centre — mutes the type in exactly the spot the crest stands. */
.hero--mast { position: relative; overflow: hidden; padding: 0; }
/* The tile is inked at #1c1c1e — the undimmed #262628 scaled by round(channel * (1 - dim))
   at dim = .25. That is the same compositing the pattern-layout swatches do with a black
   overlay at var(--dim), baked into the tile instead of stacked as an extra layer.

   Scrim and ink are a BUDGET, not two independent dials. Every step you dim the tile is a
   step the vignette no longer has to take, and the mistake to avoid is paying twice: this
   shipped briefly at .89 / .79 / .31 over a 25%-dimmed tile, which is the full original
   scrim on top of a tile that had already done most of the job, and the middle of the hero
   went to a void. Re-ink the pattern and these come with it, downward.

   THE ELLIPSE SHRANK TOO, and that is the other half of it. At 64% x 76% the horizontal
   radius was 819px on a 1280 viewport — wider than the half-width it had to cover — so the
   gradient never reached its transparent stop on screen and every pixel, edges included,
   carried ~30% black. Stacked on an already-dimmed tile that read as one enormous shadow
   rather than a pool behind the type. 50% x 62% lands the transparent stop just inside the
   frame, so the corners are genuinely untouched and the crests survive out there.

   The opacities came down hard for the same reason. These were tuned against the ORIGINAL
   #262628 ink, which needed real scrim to seat white type; #1c1c1e is 11% grey before the
   vignette touches it, so most of that work is already done inside the tile. */
.hero--mast::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse 50% 62% at 50% 46%,
    rgba(0,0,0,.70) 0%, rgba(0,0,0,.54) 45%, rgba(0,0,0,.17) 75%, rgba(0,0,0,0) 100%);
}


.hero--mast .wrap { position: relative; z-index: 2; padding-top: 84px; padding-bottom: 72px; }
.hero--mast .hero-thesis {
  font-family: Oswald, sans-serif; font-weight: 300; text-transform: uppercase;
  letter-spacing: .05em; font-size: clamp(19px, 2.5vw, 27px); line-height: 1.36;
  max-width: 26ch; margin: 0 auto; color: #fff;
}
.hero--mast .hero-thesis b { color: var(--red); font-weight: 700; }
.hero--mast .hero-note { margin-top: 16px; font-size: 12px; font-weight: 400; color: var(--muted); }



/* ---------- Home: the split hero ----------
   Type holds the left, the skull holds the right, and the sello sheet runs
   behind both without a seam.

   The ground is the CHECKERBOARD tile, not the body sheet: two crests, one
   masked and one bare, alternating so no two identical faces ever touch. That
   diagonal beat is what stops it reading as wallpaper. background-size drives
   the scale — the file is authored 57.6 square and must stay square, so pass
   ONE number or the crests go oval.

   NO VIGNETTE here, and that is deliberate. The quiet tile inks at #1c1c1e,
   which white type clears unaided; a scrim would only mute the crests the hero
   exists to show. shop.html is a different problem and keeps its own. */
.hero--split {
  text-align: left; padding: 0;
  background: #000 url("/images/brand/sello-checker-quiet.svg");
  background-size: 124px;
  border-bottom: 1px solid var(--line);
}
.hero--split .wrap {
  display: grid; grid-template-columns: 1.02fr .98fr; gap: 30px;
  align-items: center; padding-top: 72px; padding-bottom: 66px;
}

/* Open Sans 800, NOT Oswald, and sentence case. This is the only headline on
   the site set like a sentence being spoken rather than stamped, which is the
   whole point of the line. Live text, not artwork — it is the page's h1 and it
   has to be selectable, translatable and resizable. */
.hero--split h1 {
  margin: 0; font-family: "Open Sans", sans-serif; font-weight: 800;
  text-transform: none; font-size: clamp(34px, 5.2vw, 62px);
  line-height: .98; letter-spacing: -.012em; color: #fff;
}
.hero--split h1 em { font-style: normal; color: var(--red); }
.hero--split .cb { display: block; width: min(250px, 62%); height: auto; margin: 16px 0 0; }

/* font-weight:400 is not redundant — .hero p sets 700 further up this file, and
   this rule would otherwise inherit it and set the whole paragraph bold. That
   only shows on the real page: the mock used its own class, so .hero p never
   applied and the weight looked right until it shipped. */
.hero--split .hero-copy p:not(.hero-note) {
  max-width: 38ch; margin: 18px 0 0; font-weight: 400;
  font-size: 15px; line-height: 1.6; color: #c9c5c6;
}
.hero--split .btn { margin-top: 24px; }
/* max-width:none because this line would otherwise inherit the 38ch measure set
   for the paragraph above — right for prose, too narrow for a one-line spec,
   and it orphans "Non medical-grade" onto a second row. */
.hero--split .hero-note {
  margin-top: 14px; max-width: none;
  font-size: 12px; font-weight: 400; color: var(--muted);
}
.hero--split .hero-skull { width: 100%; max-width: 430px; height: auto; margin: 0 auto; }

@media (max-width: 820px) {
  /* One column, and the skull LEADS: on a phone the artwork is what is worth
     showing before the words. */
  .hero--split { text-align: center; }
  .hero--split .wrap { grid-template-columns: 1fr; padding-top: 44px; padding-bottom: 48px; }
  .hero--split .cb { margin-inline: auto; }
  .hero--split .hero-copy p:not(.hero-note) { margin-inline: auto; }
  .hero--split .hero-skull { max-width: 330px; order: -1; margin-bottom: 26px; }
}

/* ---------- Masks: the Zuma masthead ----------
   The skull leads and the type follows. Home leads with the wordmark because it
   is the front door; here you already know where you are, so the artwork gets
   the top of the page.

   Ground is the same checkerboard as home, one step louder (#2a2a2c against
   #1c1c1e). The masthead vignette from .hero--mast stays: unlike home this page
   has sixteen product cards arriving underneath, and the pool of light is what
   separates the hero from the grid.

   Sized by HEIGHT, not width. This shot is 747x1329 — far taller relative to
   its width than the 742x795 it replaced — so holding a width would tower it
   over the type. 364px tall is the middle rung of the size study.

   width:auto is load-bearing next to that height. The img carries width/height
   attributes so the browser can reserve space before decode; set the height in
   CSS and leave the width alone and the intrinsic 747 still applies, which
   squashes the art. Stating both is what lets the ratio do the work. */
.hero--zuma {
  background: #000 url("/images/brand/sello-checker-mid.svg");
  background-size: 140px;
}
.hero--zuma .wrap { padding-top: 76px; padding-bottom: 66px; }
.hero--zuma .hero-skull {
  height: 364px; width: auto; max-width: 64%; max-height: 46vh;
  aspect-ratio: 747 / 1329; margin: 0 auto 26px; display: block; object-fit: contain;
}
@media (max-width: 700px) {
  .hero--zuma .wrap { padding-top: 48px; padding-bottom: 44px; }
  .hero--zuma .hero-skull { max-height: 38vh; margin-bottom: 20px; }
}

/* ---------- Lookbook band ---------- */
.lookbook { position: relative; border-block: 1px solid var(--line); }
.lookbook > img { width: 100%; aspect-ratio: 21 / 7; object-fit: cover; }
.lookbook-cap {
  position: absolute; inset: auto 0 0 0; padding: 60px 28px 26px;
  background: linear-gradient(to top, rgba(0,0,0,.92), rgba(0,0,0,.5) 55%, rgba(0,0,0,0));
  display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap;
}
.lookbook-cap h2 { margin: 0; font-size: clamp(20px, 2.6vw, 30px); color: #fff; }
.lookbook-cap a { font-weight: 700; font-size: 14px; color: var(--red); }
.lookbook-cap a:hover { color: #fff; }
@media (max-width: 700px) { .lookbook > img { aspect-ratio: 4 / 3; } }

/* ---------- Section headings ---------- */
.section { padding: 54px 0; }
.section--tight { padding: 34px 0; }
.section-title { text-align: center; font-size: clamp(28px, 5vw, 40px); margin-bottom: 6px; }
.section-title .accent { color: var(--red); }
.section-sub { text-align: center; color: var(--muted); margin: 0 auto 34px; max-width: 560px; }
/* .section--dark used to be the exception on a white site. The whole store is dark
   now, so it is just a transparent band — anything else would punch a flat rectangle
   through the pattern. Kept because the HTML still uses the class. */
.section--dark { background: transparent; color: #fff; }
.section--dark .section-title { color: #fff; }

/* ---------- Product grid ---------- */
.grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 26px; }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px){ .grid, .grid--3 { grid-template-columns: repeat(2, 1fr); gap: 18px; } }
@media (max-width: 520px){ .grid, .grid--3 { grid-template-columns: repeat(2, 1fr); gap: 12px; } }

/* The card IS the label. The mask art is black-with-white-print, so against a white
   page the product fought its own background; against black, a white card frames it
   and the print becomes the product — which is the only thing anyone is buying.
   The photos are already shot on white, so this cost a re-shoot of nothing. */
.card { display: block; background: var(--paper); color: var(--ink-on-paper); }
.card .thumb { position: relative; overflow: hidden; background: var(--paper); aspect-ratio: 1 / 1; }
/* :not(.badge) is load-bearing. These two rules exist for the product PHOTO — but the sale
   badge is now an <img> inside .thumb too, and unscoped it inherits width/height:100% +
   object-fit:cover, blows up to fill the entire card, and then scales on hover. It used to be
   a <span>, which is why this never bit before. */
.card .thumb img:not(.badge) { width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
.card .thumb::after {
  content: ""; position: absolute; inset: 0; background: rgba(255,0,0,0.3); opacity: 0; transition: opacity .2s ease;
}
.card:hover .thumb::after { opacity: 1; }
.card:hover .thumb img:not(.badge) { transform: scale(1.04); }
/* The distressed mark, stamped on the corner of the card. It is red on the card's white,
   so the chips in the lettering read as white speckle — the texture works the same way it
   does on black, just inverted. */
.card .badge {
  position: absolute; top: 6px; left: 6px; z-index: 2;
  width: 108px; height: auto; display: block;
}
.card .info { text-align: center; padding: 12px 8px 14px; border-top: 2px solid #000; }
.card .info .name { font-family: "Oswald", sans-serif; font-weight: 700; text-transform: uppercase; font-size: 17px; letter-spacing: .04em; margin: 0 0 3px; }

/* ---------- A mask's name is a proper noun ----------
   Sello Blanco, El Jaguar, La Zorra. The catalog already stores them in title case; three
   separate rules were shouting them back in caps — the card, the product page's h1 (via the
   global h1..h4 uppercase), and the cart line. This sets them back to the name as written,
   in the one place all three can be governed together.

   The tracking has to come down with the case. The .04em was tuned for all-caps, where the
   gaps between letterforms are even; in title case it reads as a gappy, broken word.

   Only the NAME is affected. "Shop All Masks", buttons and section heads stay uppercase — the
   point is that a name is not a label. */
.card .info .name,
.pdp .info h1,
.line-item .li-name { text-transform: none; letter-spacing: .005em; }
.card .info .price { font-family: "Oswald", sans-serif; font-weight: 500; font-size: 17px; color: #333; font-variant-numeric: tabular-nums; }
.price .was { color: var(--red); text-decoration: line-through; margin-right: 8px; }
/* inherit, do NOT pin a colour: the same .price markup renders inside a white card
   (where the context is dark ink) AND on the black product page (where it's white).
   Hardcoding #111 here made the price invisible on all 16 mask pages. */
.price .now { color: inherit; }

/* ---------- Photo strip (lifestyle row) ---------- */
.photo-strip { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.photo-strip img { width: 100%; border-radius: 3px; }
@media (max-width: 700px){ .photo-strip { grid-template-columns: 1fr; } }

/* ---------- Product detail ---------- */
.pdp { display: grid; grid-template-columns: 1fr 1fr; gap: 46px; padding: 44px 0; }
@media (max-width: 820px){ .pdp { grid-template-columns: 1fr; gap: 26px; } }
/* Same idea as the card: the mask photo sits on its own white plate, and the plate
   sits on the black page. Don't tint this — the studio shots ARE white. */
.pdp .gallery .main { position: relative; border: 0; border-radius: 4px; overflow: hidden; aspect-ratio: 1/1; background: var(--paper); }
/* contain, not cover: the studio shots are 3:2 and would be cropped. Square art fills the box either way. */
.pdp .gallery .main img { width: 100%; height: 100%; object-fit: contain; }
.pdp .gallery .thumbs { display: flex; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.pdp .gallery .thumbs button { width: 74px; height: 74px; border: 2px solid var(--line); background: var(--paper); padding: 0; border-radius: 4px; overflow: hidden; }
.pdp .gallery .thumbs button.active { border-color: var(--red); }
.pdp .gallery .thumbs img { width: 100%; height: 100%; object-fit: contain; }
.pdp .gallery .gnav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border: 0; border-radius: 50%;
  background: rgba(0,0,0,.55); color: #fff;
  font-family: "Oswald", sans-serif; font-size: 30px; line-height: 1; padding: 0 0 4px;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .2s ease, background .2s ease;
}
.pdp .gallery .main:hover .gnav, .pdp .gallery .gnav:focus-visible { opacity: 1; }
.pdp .gallery .gnav:hover { background: var(--red); }
.pdp .gallery .gnav.prev { left: 10px; }
.pdp .gallery .gnav.next { right: 10px; }
/* touch devices have no hover — keep the arrows visible */
@media (hover: none) { .pdp .gallery .gnav { opacity: 1; } }
.pdp .info h1 { font-size: clamp(30px, 5vw, 46px); }
.pdp .info .price { font-family: "Oswald", sans-serif; font-size: 28px; margin: 4px 0 18px; }
.pdp .info .rte { border-top: 1px solid var(--line); padding-top: 18px; margin-top: 4px; }
.pdp .info .rte ul { padding-left: 20px; }
.pdp .buy { display: flex; gap: 12px; align-items: stretch; margin: 22px 0 10px; }
.qty { display: inline-flex; border: 2px solid var(--line); border-radius: 3px; overflow: hidden; }
.qty button { width: 42px; border: 0; background: #1a1a1d; font-size: 20px; color: #fff; }
.qty button:hover { background: var(--red); }
.qty input { width: 52px; border: 0; text-align: center; font-size: 16px; font-family: "Oswald", sans-serif; background: #111114; color: #fff; }
.pdp .meta { color: var(--muted); font-size: 13px; margin-top: 14px; }
.pdp .meta .ship { color: var(--red); font-weight: 600; }

/* ---------- Cart drawer ---------- */
.drawer-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.5); opacity: 0; visibility: hidden; transition: .2s; z-index: 100; }
.drawer-overlay.open { opacity: 1; visibility: visible; }
.drawer {
  position: fixed; top: 0; right: 0; height: 100%; width: 400px; max-width: 90vw; z-index: 101;
  background: #000 var(--sello); background-size: 128px 148px;
  color: var(--ink);
  border-left: 1px solid var(--line);
  transform: translateX(100%); transition: transform .25s ease; display: flex; flex-direction: column;
}
.drawer.open { transform: none; }
.drawer .drawer-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px; background: #000; color: #fff; }
.drawer .drawer-head h3 { margin: 0; color: #fff; }
.drawer .drawer-head button { background: none; border: 0; color: #fff; font-size: 24px; }
.drawer .items { flex: 1; overflow-y: auto; padding: 8px 20px; }
.drawer .foot { border-top: 1px solid var(--line); padding: 18px 20px; }
.drawer .foot .row { display: flex; justify-content: space-between; font-family: "Oswald", sans-serif; font-size: 20px; margin-bottom: 14px; }

.line-item { display: grid; grid-template-columns: 64px 1fr auto; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--line); align-items: center; }
.line-item img { width: 64px; height: 64px; object-fit: cover; border: 1px solid var(--line); border-radius: 3px; }
.line-item .li-name { font-family: "Oswald", sans-serif; font-weight: 600; text-transform: uppercase; font-size: 15px; }
.line-item .li-sub { color: var(--muted); font-size: 13px; }
.line-item .li-remove { background: none; border: 0; color: var(--muted); font-size: 12px; text-decoration: underline; padding: 0; }
.line-item .li-remove:hover { color: var(--red); }
.li-price { font-family: "Oswald", sans-serif; font-size: 16px; white-space: nowrap; }
.cart-empty { text-align: center; color: var(--muted); padding: 40px 0; }

/* ---------- Cart page / checkout ---------- */
.two-col { display: grid; grid-template-columns: 1.4fr 1fr; gap: 40px; align-items: start; padding: 40px 0; }
@media (max-width: 820px){ .two-col { grid-template-columns: 1fr; } }
.panel { border: 1px solid var(--line); border-radius: 5px; padding: 22px; }
.panel h3 { border-bottom: 2px solid var(--red); padding-bottom: 8px; }
.summary-row { display: flex; justify-content: space-between; padding: 7px 0; }
.summary-row.total { border-top: 1px solid var(--line); margin-top: 8px; padding-top: 14px; font-family: "Oswald", sans-serif; font-size: 22px; }
.field { margin-bottom: 14px; }
.field label { display: block; font-family: "Oswald", sans-serif; text-transform: uppercase; font-size: 13px; letter-spacing: .04em; margin-bottom: 5px; }
.field input, .field select {
  width: 100%; padding: 11px 12px; border: 1px solid #2e2e33; border-radius: 4px; font-size: 15px; font-family: inherit;
  background: #111114; color: #fff;
}
.field input::placeholder { color: #6b6769; }
.field input:focus, .field select:focus { outline: 2px solid var(--red); border-color: var(--red); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.notice { background: #2a0d0d; border: 1px solid #5c1f1f; color: #ff8f8f; padding: 12px 14px; border-radius: 5px; font-size: 14px; }
#payment-element { min-height: 40px; }

/* ---------- Rich text (policy pages) ---------- */
.rte { max-width: 820px; margin: 0 auto; }
.rte h1, .rte h2 { color: var(--red); text-align: center; }
.rte h3 { color: #fff; }
.rte p { margin: 0 0 1em; }
.rte a { color: var(--red); text-decoration: underline; }
.rte ul { margin: 0 0 1em; }

/* ---------- Newsletter band ---------- */
.newsletter { background: #000; color: #fff; text-align: center; padding: 46px 20px; }
.newsletter h3 { color: var(--red); font-size: 22px; }
.newsletter form { display: flex; gap: 10px; max-width: 460px; margin: 16px auto 0; }
.newsletter input { flex: 1; padding: 12px 14px; border: 0; border-radius: 3px; font-size: 15px; }
@media (max-width: 480px){ .newsletter form { flex-direction: column; } }

/* ---------- Footer ---------- */
/* The header stays flat black. The footer does NOT — and it does not get a tile of its own either.
   It paints no background at all, so the page's sello sheet runs straight down through it: same
   tile, same phase, no seam at the border. That is the only honest reading of "extend the pattern
   to the footer" — give the footer its own background-image and the tile phase restarts at its top
   edge, which draws a hairline of mismatched crests right where you least want one.

   Painting nothing also makes the footer correct on every page for free: the shop pages hand it
   the full-strength tile, the long-read pages hand it the quiet one. The ground is pure black in
   both cases. Put a colour back here and you break both at once.

   The header cannot do this. It is sticky, so it has to stay opaque or the page smears through it
   as you scroll. The two are no longer a matched pair, on purpose. */
.site-footer {
  background: transparent;
  color: var(--red); padding: 46px 0 30px; text-align: center;
  border-top: 1px solid var(--line);
}
.site-footer .cols { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 30px; }
@media (max-width: 700px){ .site-footer .cols { grid-template-columns: 1fr; gap: 22px; } }
.site-footer h4 { color: #fff; font-size: 16px; margin-bottom: 12px; }
.site-footer a { color: #bbb; }
.site-footer a:hover { color: var(--red); }
.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer ul li { margin-bottom: 7px; }
.site-footer .foot-brand img { height: 42px; margin-bottom: 14px; }
.site-footer .legal { border-top: 1px solid #222; margin-top: 26px; padding-top: 16px; font-size: 13px; color: #777; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
.site-footer .foot-badges { display: grid; grid-template-columns: 1fr 1.15fr 1fr; gap: 28px; align-items: center; max-width: 1060px; margin: 0 auto; }
/* cart + sale badges are links; blockify so they sit in the grid exactly as the bare imgs did */
.site-footer .foot-badges a { display: block; line-height: 0; }
.site-footer .foot-badges a img { transition: opacity .2s ease; }
.site-footer .foot-badges a:hover img { opacity: .78; }
/* NO mix-blend-mode. These carry real alpha now — the black inside each piece is opaque
   on purpose, so the sello pattern stops showing through the cart body and the mask. */
.site-footer .foot-badges img { width: 100%; height: auto; object-fit: contain; }
.site-footer .foot-badges .sale { max-height: 150px; }
/* The cart is SQUARE now — the badge it replaced was 2.4:1. Sharing the SALE's 150px cap left
   it visibly undersized next to it, because 150px of height buys a wide mark far more presence
   than it buys a square one. It gets its own cap. */
.site-footer .foot-badges .cart { max-height: 200px; }

/* The cart hovers like the SALE mark does — a dim, nothing more. It used to cross-fade to a
   second, all-white drawing of the same cart (confusingly named paletero-cart-red.svg); that
   drawing is deleted and the swap is gone for good. Do not add it back. The dim comes from the
   shared `.foot-badges a:hover img` rule above, so there is deliberately no cart hover here. */
.site-footer .foot-badges .lockup { max-height: 260px; }
@media (max-width: 700px){ .site-footer .foot-badges { grid-template-columns: 1fr; gap: 12px; } }
/* Moctezuma is a signature, not a billboard. It was running 1000px wide across the
   footer and shouting over the medallion above it. */
.site-footer .foot-wordmark { margin: 18px auto 26px; }
.site-footer .foot-wordmark img { max-width: 340px; width: 62%; height: auto; margin: 0 auto; }
.site-footer .foot-nav { display: flex; justify-content: flex-start; flex-wrap: wrap; gap: 8px 24px; margin-bottom: 12px; }
.site-footer .foot-nav a { color: var(--red); font-family: "Open Sans", sans-serif; font-weight: 700; text-transform: none; letter-spacing: 0; font-size: 15px; }
.site-footer .foot-nav a:first-child, .site-footer .foot-nav a:hover { color: #fff; }
.site-footer .foot-credit { color: #e23b3b; font-size: 13px; font-weight: 700; font-family: "Open Sans", sans-serif; letter-spacing: 0; text-align: left; }

/* ---------- Home showcase (packaging + hero) ---------- */
.showcase { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.showcase img { width: 100%; background: var(--paper); }
@media (max-width: 700px){ .showcase { grid-template-columns: 1fr; } }

/* ---------- Page intro banner ---------- */
/* Transparent so the pattern runs straight through it, plus a hairline to keep the
   band reading as a band. */
/* 34/30, down from 56/48. Changing it HERE rather than adding a class to five
   pages is deliberate: the reading pages (care guide, shipping, privacy, terms,
   store policy) are the only ones left using .page-head bare — sale overrides
   the padding in --sale and the funnel pages override it in --tight — so this
   moves exactly those five and nothing else.

   They KEEP their vignette. Stripping it on checkout was a checkout argument: a
   wash above a payment form reads as chrome. That does not transfer to a page of
   body copy, where a little darkness behind the heading is what seats it on the
   sello sheet. The ellipse is sized 104% of the head's own height, so it shrinks
   with this padding instead of needing its own adjustment. */
.page-head { background: transparent; color: #fff; text-align: center; padding: 34px 20px 30px; border-bottom: 1px solid var(--line); }
.page-head h1 { color: #fff; font-size: clamp(30px, 6vw, 48px); margin: 0; }
.page-head .crumb { color: #999; font-size: 13px; margin-top: 6px; }

/* Every page head sits in the same pool of light the masthead does: the vignette darkens the
   middle so the type has something to sit on, and dies at the edges so the sello tiles stay
   alive in the corners. Without it a page head is just words floating on wallpaper.
   The ::after is positioned, so unpositioned children would render UNDER it — the children
   are lifted onto their own layer to stay on top of the wash. */
.page-head { position: relative; overflow: hidden; }
.page-head::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 70% 104% at 50% 50%,
    rgba(0,0,0,.92) 0%, rgba(0,0,0,.8) 45%, rgba(0,0,0,.3) 76%, rgba(0,0,0,0) 100%);
}
.page-head > * { position: relative; z-index: 2; }

/* On the sale page the distressed mark IS the headline, so the words underneath step down
   and become the subhead. The chips in the lettering are real holes — the sello pattern
   reads straight through them, which is the whole point of the artwork. */
.page-head--sale { padding-top: 46px; }
.page-head--sale .sale-mark { display: block; width: min(320px, 64%); height: auto; margin: 0 auto 20px; }
.page-head--sale h1 { font-size: clamp(21px, 3.2vw, 31px); }

/* ---------- Sale: shadow off, pulled up ----------
   The wash is removed here only, and not for taste. The chips in the SALE mark
   are REAL HOLES — the sello sheet is meant to read straight through them,
   which is the whole point of the artwork — and a scrim behind it fills them
   with grey. The subhead still clears comfortably: white on the sheet's ink is
   about 15:1.

   46px of top padding was sized for a head sitting in a pool of light, which
   needs air around it to look deliberate. With the wash gone the mark can sit
   closer to the nav without reading as cramped, and the grid arrives sooner. */
.page-head--sale::after { display: none; }
.page-head--sale { padding-top: 26px; padding-bottom: 30px; }
.page-head--sale .sale-mark { margin-bottom: 14px; }
.page-head--sale .crumb { margin-top: 4px; }

/* ---------- Cart + checkout: the money pages ----------
   Pulled up harder than sale. A checkout head is not a hero: every pixel above
   the form sits between a decided customer and the field they came to fill in.
   Cart gets the identical treatment because it is the step immediately before —
   move one and not the other and the funnel jolts between them.

   Shadow off for a different reason than sale. There is no artwork here, just a
   word and a line of trust copy, and a heavy wash directly above a payment form
   reads as chrome. The crumb is deliberately NOT shrunk to make room: "Secure
   payment - you never leave cartelmasks.com" is the highest-value line on the
   page, and it is what earns the card number. */
.page-head--tight::after { display: none; }
.page-head--tight { padding-top: 22px; padding-bottom: 22px; }
.page-head--tight h1 { font-size: clamp(24px, 4vw, 34px); }
.page-head--tight .crumb { margin-top: 7px; color: #a9a4a6; font-size: 13px; }

/* .panel ships with a border and a radius but NO background, so the sello sheet
   runs straight through the form fields. Everywhere else that is the point; on
   the two pages that take money it is the one place legibility beats brand.

   #141417 rather than pure black on purpose: the inputs are #111114, so a panel
   a shade LIGHTER makes every field read as an inset well. Flip the two and the
   fields float, which is exactly the fussiness being removed. The pattern still
   holds the margins, so the page is unmistakably Cartel Masks — it just stops
   happening underneath the card number. */
body[data-page="cart"] .panel,
body[data-page="checkout"] .panel { background: #141417; }

/* The Instagram chip is the site's ONLY outbound link, and these are the two
   screens where someone has already decided. It stays everywhere else, where
   discovery is the job. */
body[data-page="cart"] .foot-social,
body[data-page="checkout"] .foot-social { display: none; }

/* ---------- Filters ---------- */
.filters { display: flex; gap: 10px; justify-content: center; margin-bottom: 28px; flex-wrap: wrap; }
/* Inverted for the black page: outline by default, filled red when it's the one you're on. */
.filters button {
  border: 2px solid #3a3a3e; background: transparent; color: #fff; font-family: "Oswald", sans-serif; text-transform: uppercase;
  font-size: 14px; letter-spacing: .04em; padding: 8px 18px; border-radius: 2px;
}
.filters button.active, .filters button:hover { background: var(--red); border-color: var(--red); color: #fff; }

/* ---------- Mobile nav ---------- */
@media (max-width: 860px){
  .nav-toggle { display: block; }
  .main-nav {
    position: absolute; top: 66px; left: 0; right: 0; background: #000; flex-direction: column; gap: 0;
    padding: 8px 20px 16px; border-bottom: 3px solid var(--red); display: none;
  }
  .main-nav.open { display: flex; }
  .main-nav a { width: 100%; padding: 12px 0; border-bottom: 1px solid #222; }

  /* The lockup is 6.55:1, so at height:46px it demands 301px — but a 390px phone has only
     ~225px left in this row once the burger and the cart are in it. .brand is flex:0 0 auto,
     so it gave up nothing and shoved the CART CLEAN OFF the right edge of the screen.
     Size it off the VIEWPORT, not off its parent: the lockup SVG carries a viewBox but no
     width/height, so it has a ratio and no intrinsic size — a percentage max-width inside a
     shrinkable flex item resolves circularly and collapses it to 0x0. It needs a definite
     width, just a fluid one. 56vw is what the row can spare at 320px with room to breathe. */
  .site-header .wrap { padding: 0 14px; gap: 12px; }
  .brand img { width: min(280px, 56vw); height: auto; }
}

/* ---- "We're not open yet" bar. Sits above the header on every page while the
        shop is shut, so nobody gets as far as the payment form before finding
        out. Removed automatically the moment the live Stripe keys go in. ---- */
.notice-bar {
  background: var(--red);
  color: #fff;
  font-size: 14px;
  letter-spacing: .02em;
  text-align: center;
  padding: 10px 0;
}
.notice-bar strong { text-transform: uppercase; letter-spacing: .08em; }
.notice-bar .wrap { padding: 0 20px; }

/* A disabled buy/checkout button should read as "not yet", not as broken. */
.btn[disabled] {
  background: #333;
  border-color: #333;
  color: #999;
  cursor: not-allowed;
  pointer-events: none;
}

/* ---- Shipping rate table (shipping.html) — built from data/shipping.json ---- */
.rate-table { width: 100%; border-collapse: collapse; margin: 18px 0 26px; }
.rate-table th,
.rate-table td { padding: 11px 12px; border-bottom: 1px solid var(--line); text-align: left; }
.rate-table th { font-family: Oswald, sans-serif; text-transform: uppercase; letter-spacing: .06em;
                 font-size: 13px; border-bottom: 2px solid var(--ink); }
.rate-table td:not(:first-child),
.rate-table th:not(:first-child) { text-align: right; white-space: nowrap; }

/* ============================================================
   THE TOUR  (tour.html)
   ============================================================ */
/* Paints NOTHING, and that is the whole design. The page's sello sheet runs down the canvas from
   the header to the footer without a break, and this section lets it through untouched — the city
   you see is that same sheet, seen through a city-shaped hole in the SVG's black sky (see the note
   in tour.html). One pattern, one scale, one phase, from the top of the page to the bottom.

   Put `background: #000` back here and the hero goes opaque: the sheet stops dead at the top of
   this section and starts again below it, and the city has to carry its own copy of the pattern —
   which is where the old bug lived, because that copy scaled with the viewport while the page's
   stayed at a fixed pixel size. They could only line up at one window width. Do not re-add it. */
.tour-hero { position: relative; overflow: hidden; background: transparent; }
/* Overhangs the section by a hair, and the exact amount is load-bearing — measured, not guessed.
   The artwork is a skyline standing on a big solid block, and the keyline traces that block's
   outer border as well as the rooflines. Those borders are the two long verticals that used to
   drop down the edge of the section and stop dead. In artwork units (the viewBox is 1102.8 wide):

       left drop line   x =    6 ..   10
       right drop line  x = 1097 .. 1100
       THE BUILDINGS    x =   10 .. 1083

   So the drop lines sit in the ~12 units of dead margin outside the buildings, and 12 units is all
   you have to hide. Overhang 1.1% each side and they clip away with every building still intact.
   An earlier pass used 7%, which hid 68 units on the left and 68 on the right — that is 58 and 48
   units of actual BUILDING, and it cropped a couple off each end. Widen this and you start eating
   the skyline; narrow it and the drop lines come back. There is no slack. */
.tour-sky {
  position: absolute; top: 0; left: -1.1%;
  width: 102.2%; height: auto; pointer-events: none;
  color: #414042;   /* the keyline. It is the sello's own grey — bright enough to read as a city,
                       quiet enough that the white cart stays the only white thing on the page.
                       The keyline draws with currentColor, so this is the only place to change it. */
}
.tour-hero-inner {
  position: relative; z-index: 2;
  padding: 190px 20px 0;
  display: grid; grid-template-columns: 1.12fr .88fr; gap: 36px; align-items: end;
}
.tour-cb { width: min(380px, 84%); height: auto; margin-bottom: 20px; }
.tour-hero-copy h1 { font-size: clamp(28px, 4vw, 44px); color: #fff; margin: 0 0 18px; }
.tour-hero-copy h1 em { font-style: normal; color: var(--red); }
.tour-hero-copy p { max-width: 46ch; color: #cfcbcc; font-size: 16px; line-height: 1.7; margin: 0 0 14px; }
.tour-hero-copy p strong { color: #fff; font-weight: 600; }
.tour-cart { width: 100%; max-width: 460px; height: auto; margin: 0 auto -2px; }
.tour-facts {
  position: relative; z-index: 2; list-style: none; display: flex; gap: 26px; flex-wrap: wrap;
  max-width: var(--maxw); margin: 0 auto; padding: 16px 20px 0;
  border-top: 1px solid rgba(255,255,255,.14);
  font-family: "Oswald", sans-serif; text-transform: uppercase; letter-spacing: .16em;
  font-size: 11px; color: var(--muted);
}
@media (max-width: 820px) {
  /* One column: the city shrinks with the viewport, so the copy lands low on the
     silhouette where it is reading on clean pattern. */
  .tour-hero-inner { grid-template-columns: 1fr; padding-top: 150px; }
  .tour-cart { max-width: 330px; }
}

.tour-lede { font-size: clamp(19px, 2.4vw, 24px); color: #cfcbcc; max-width: 54ch; margin: 0 0 12px; }
.tour-lede strong { color: #fff; font-weight: 700; }

/* The route. The rail runs almost dead through the three defeats and only ignites at
   Shiprock — that IS the shape of the trip, so the line encodes it instead of decorating. */
.route { list-style: none; margin: 44px 0 0; padding: 0; position: relative; }
.route::before {
  content: ""; position: absolute; left: 23px; top: 14px; bottom: 14px; width: 2px;
  background: linear-gradient(to bottom, #3a0000 0%, #4a0000 55%, #8a0000 72%, var(--red) 88%);
}
.stop { position: relative; padding: 0 0 38px 76px; }
.stop:last-child { padding-bottom: 0; }
.stop .pin {
  position: absolute; left: 0; top: 0; width: 48px; height: 48px; border-radius: 50%;
  background: #000; border: 2px solid #5a2020; color: #8a5a5a;
  display: grid; place-items: center;
  font-family: "Oswald", sans-serif; font-weight: 700; font-size: 15px; font-variant-numeric: tabular-nums;
}
.stop h2 { font-size: 24px; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 0 0 10px; color: #fff; }
.stop h2 span { font-family: "Open Sans", sans-serif; font-weight: 700; text-transform: none; letter-spacing: 0; font-size: 13px; color: var(--muted); }
/* Outcome, not ornament: three greys and then one red. */
.stop .out {
  display: inline-block; font-family: "Oswald", sans-serif; font-weight: 600; text-transform: uppercase;
  letter-spacing: .14em; font-size: 10px; padding: 4px 9px;
  border: 1px solid #3a3a3e; color: var(--muted); margin: 0 0 12px;
}
.stop p { color: var(--muted); font-size: 16px; line-height: 1.75; max-width: 58ch; margin: 0 0 12px; }
.stop p strong { color: #ddd9da; font-weight: 600; }
/* The promise at the end of Shiprock. Four words, so it doesn't need decoration — it needs
   room and it needs to be the brightest thing in the paragraph stack. */
.stop p.coda { color: #fff; font-size: 20px; font-weight: 600; margin: 22px 0 0; }
.stop--turn .pin { background: var(--red); border-color: var(--red); color: #fff; }
.stop--turn .out { border-color: var(--red); background: var(--red); color: #fff; }
.stop--turn h2 { font-size: 30px; }
.stop--turn h2 em { font-style: normal; color: var(--red); }
.stop--turn p { color: #cfcbcc; }
@media (max-width: 640px) {
  .route::before { left: 17px; }
  .stop { padding-left: 56px; }
  .stop .pin { width: 36px; height: 36px; font-size: 13px; }
  .stop--turn h2 { font-size: 24px; }
}

/* The 2021 poster, presented as an artifact rather than as decoration: a black plate,
   a date, and a caption. The date is the one place the gold in the drawing gets to
   speak on the page. */
.artifact {
  margin: 52px 0 0; padding: 34px 20px 28px;
  background: #000; border: 1px solid var(--line);
  text-align: center;
}
.artifact img { display: block; width: 100%; max-width: 560px; height: auto; margin: 0 auto; }
.artifact figcaption {
  max-width: 46ch; margin: 24px auto 0;
  color: var(--muted); font-size: 14px; line-height: 1.7;
}
.artifact-date {
  display: block; margin-bottom: 8px;
  font-family: "Oswald", sans-serif; text-transform: uppercase;
  letter-spacing: .2em; font-size: 12px; color: var(--gold);
}

.tour-end { border-top: 1px solid var(--line); margin-top: 48px; padding-top: 40px; text-align: center; }
.tour-end p { color: var(--muted); max-width: 46ch; margin: 0 auto 22px; }
.tour-end p strong { color: #fff; font-weight: 600; }
/* Signs the page off the way he ended the pitch. Last thing you read. */
.tour-end .signoff {
  margin: 34px auto 0; color: #fff;
  font-family: "Oswald", sans-serif; text-transform: uppercase;
  letter-spacing: .34em; font-size: 15px;
}

/* ---- Instagram. The site's only outbound link. ---- */
.foot-social { display: flex; justify-content: center; margin: 0 0 26px; }
.foot-social a {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 11px 20px; border: 1px solid var(--line); color: #fff;
  font-family: "Oswald", sans-serif; text-transform: uppercase; letter-spacing: .16em;
  font-size: 12px; transition: color .15s ease, border-color .15s ease;
}
.foot-social a:hover, .foot-social a:focus-visible { color: var(--red); border-color: var(--red); }
.foot-social svg { width: 18px; height: 18px; display: block; flex: 0 0 auto; }

/* ---- The standing "this is not PPE" line in the footer ---- */
.foot-disclaimer { max-width: 640px; margin: 14px auto 0; font-size: 12px; line-height: 1.6;
                   color: var(--muted); text-align: center; }
.foot-disclaimer a { color: var(--muted); text-decoration: underline; }
