/* ==========================================================================
   MerchStamp — shared shell (nav, footer, type system, buttons, tiles)
   Loaded on every page. Page-specific files (anime.css, gag.css, dark.css,
   about.css, home.css) load after this one and only add to it.
   ========================================================================== */

:root{
  --black:        #0a0a0a;
  --charcoal:     #141414;
  --charcoal-2:   #1c1b19;
  --ink:          #1b1b1b;
  --paper:        #f7f6f3;
  --paper-dim:    #ece8e0;
  --cream:        #efece3;
  --accent:       #b3122d;
  --accent-bright:#e2213f;
  --accent-glow:  rgba(179,18,45,.45);
  --gold:         #d9a531;
  --gold-bright:  #f0c352;
  --gold-glow:    rgba(217,165,49,.32);
  --muted-light:  #6b6b6b;
  --muted-dark:   #a49e93;
  --white:        #f5f3ee;
  --line-dark:    rgba(245,243,238,.14);
  --line-light:   rgba(27,27,27,.12);

  --font-display: 'Anton', 'Arial Narrow Bold', Impact, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  --nav-h: 76px;
}

*, *::before, *::after{ box-sizing: border-box; }
html{ scroll-behavior: smooth; }
/* Sideways-scroll safety net, added 2026-09-18. A third-party embed (the
   reCAPTCHA in the signup panel) was forcing the document 53px wider than a
   phone viewport, so the page could be dragged left and a white strip showed
   beside it. The real cause is fixed in the .sib-captcha rules at the bottom of
   this file; this is the backstop so no future embed can do it again.
   `clip` not `hidden` on purpose: overflow-x:hidden on html silently kills
   position:sticky on every descendant, which would break the nav. */
html, body{ overflow-x: clip; }
body{
  margin: 0;
  max-width: 100%;
  font-family: var(--font-body);
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img{ max-width: 100%; display: block; }
a{ color: inherit; text-decoration: none; }
ul{ margin: 0; padding: 0; list-style: none; }
h1,h2,h3{
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: .01em;
  line-height: .98;
  margin: 0;
  font-weight: 400;
}
p{ margin: 0; }
.eyebrow{
  font-family: var(--font-body);
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  font-size: .72rem;
}

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- layout helpers ---------- */
.wrap{ max-width: 1180px; margin: 0 auto; padding: 0 28px; }
main{ display: block; }

/* ---------- buttons ---------- */
.btn{
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .82rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 15px 28px;
  border-radius: 3px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform .18s ease, background-color .18s ease, color .18s ease, border-color .18s ease;
  white-space: nowrap;
}
.btn:hover{ transform: translateY(-2px); }
.btn-accent{ background: var(--accent); color: var(--white); }
.btn-accent:hover{ background: var(--accent-bright); }
.btn-outline-dark{ background: transparent; color: var(--white); border-color: var(--line-dark); }
.btn-outline-dark:hover{ border-color: var(--white); }
.btn-outline-light{ background: transparent; color: var(--ink); border-color: var(--line-light); }
.btn-outline-light:hover{ border-color: var(--ink); }

/* ---------- promo bar ----------
   Sitewide announcement strip, sits above the nav on every page. Deliberately
   a slim single row — it scrolls away with the page (the nav below it is the
   sticky element), so it never competes with a page's own hero. The <form>
   inside is wired for the hidden-iframe POST trick (see js/promo.js) so it
   never navigates away, but it has no live endpoint yet — see the HTML
   comment next to the <form> tag on each page for the two placeholder values
   that need swapping in before this goes live. */
.promo-bar{
  background: var(--accent-bright);
  color: var(--white);
}
.promo-bar-inner{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px 22px;
  flex-wrap: wrap;
  padding: 11px 28px;
  text-align: center;
}
.promo-headline{
  font-size: .84rem;
  font-weight: 600;
  letter-spacing: .01em;
}
.promo-headline strong{
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: .03em;
  text-transform: uppercase;
  margin-right: 2px;
}
.promo-form{
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}
/* .promo-form sets its own display:flex, which as an author rule beats the
   UA stylesheet's [hidden]{display:none} — without this, toggling the
   `hidden` attribute via JS (see js/promo.js) does nothing visible. */
.promo-form[hidden]{ display: none; }
.promo-input{
  font-family: var(--font-body);
  font-size: .82rem;
  padding: 8px 12px;
  min-width: 210px;
  border-radius: 3px;
  border: 1px solid rgba(245,243,238,.45);
  background: rgba(10,10,10,.16);
  color: var(--white);
}
.promo-input::placeholder{ color: rgba(245,243,238,.75); }
.promo-input:focus{ outline: 2px solid var(--white); outline-offset: 1px; background: rgba(10,10,10,.26); }
.promo-submit{
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .76rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 8px 20px;
  border-radius: 3px;
  border: none;
  background: var(--black);
  color: var(--white);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .15s ease, transform .15s ease;
}
.promo-submit:hover{ background: var(--charcoal-2); transform: translateY(-1px); }
.promo-thanks{
  font-size: .84rem;
  font-weight: 700;
}
.sr-only{
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 640px){
  .promo-bar-inner{
    flex-direction: column;
    padding: 14px 20px;
    gap: 10px;
  }
  .promo-form{ width: 100%; max-width: 380px; }
  .promo-input{ flex: 1; min-width: 0; }
}

/* ---------- nav ---------- */
.site-nav{
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: var(--charcoal);
  border-bottom: 1px solid var(--line-dark);
}
.site-nav .wrap{
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.brand{
  font-family: var(--font-display);
  color: var(--white);
  font-size: 1.35rem;
  letter-spacing: .04em;
  display: flex;
  align-items: baseline;
  gap: 2px;
}
.brand span{ color: var(--accent); }
.nav-links{
  display: flex;
  align-items: center;
  gap: 34px;
}
.nav-links a{
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted-dark);
  padding: 8px 2px;
  border-bottom: 2px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.nav-links a:hover,
.nav-links a[aria-current="page"]{
  color: var(--white);
  border-color: var(--accent);
}
.nav-cta{
  margin-left: 6px;
  padding: 10px 20px;
  font-size: .72rem;
}
/* `.nav-links a` (0,1,1) out-specifies `.btn-accent` (0,1,0), so the red CTA
   was rendering its label in the muted grey used by the plain nav links.
   Pre-existing; caught on a headless screenshot 2026-09-18. */
.nav-links a.nav-cta{ color: var(--white); }
/* "Shop All" is the one nav item that has to survive being skimmed, so it gets
   the white treatment while the rest sit muted. */
.nav-links a.nav-shop{ color: var(--white); }
.nav-links a.nav-shop::before{
  content: "";
  display: inline-block;
  width: 5px; height: 5px;
  background: var(--accent);
  border-radius: 50%;
  margin-right: 8px;
  vertical-align: middle;
}

/* ---------- menu button ----------
   Reworked 2026-09-18. It was a bare 40px hamburger with no label and no
   border, and a real visitor did not see it at all — he could not find the
   products. NN/g's current guidance (June 2025, on top of their 2016 study
   measuring a 20%+ drop in discoverability for hidden navigation) is to label
   the icon with the word "Menu" and give it enough contrast and padding to
   read as a control. So: bars + the word, inside a visible bordered pill. */
.nav-toggle{
  display: none;
  align-items: center;
  gap: 10px;
  height: 40px;
  padding: 0 14px;
  border: 1px solid rgba(245,243,238,.38);
  border-radius: 3px;
  background: rgba(245,243,238,.07);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}
.nav-toggle:hover{ background: rgba(245,243,238,.14); border-color: var(--white); }
.nav-toggle:focus-visible{ outline: 2px solid var(--accent-bright); outline-offset: 2px; }
.nav-toggle-word{
  font-family: var(--font-body);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--white);
  line-height: 1;
}
.nav-toggle-bars{
  position: relative;
  display: block;
  flex: 0 0 18px;
  width: 18px;
  height: 2px;
  background: var(--white);
  transition: background-color .2s ease;
}
.nav-toggle-bars::before,
.nav-toggle-bars::after{
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 2px;
  background: var(--white);
  transition: transform .2s ease, top .2s ease;
}
.nav-toggle-bars::before{ top: -6px; }
.nav-toggle-bars::after{ top: 6px; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars{ background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before{ top: 0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after{ top: 0; transform: rotate(-45deg); }

@media (max-width: 860px){
  .nav-links{
    /* Hangs off the bottom of the header, not from a fixed 76px down the
       viewport. It used to be `position:fixed; inset: var(--nav-h) 0 0 0`,
       which assumed the header was flush to the top of the screen. It is not:
       the promo bar sits above it and pushes it down, so the open panel was
       overlapping the header and swallowing the brand and the Close button.
       .site-nav is position:sticky, so it is the positioning ancestor here. */
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: calc(100dvh - var(--nav-h));
    background: var(--charcoal);
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
    gap: 0;
    padding: 10px 28px 28px;
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .18s ease, transform .18s ease, visibility .18s;
  }
  .nav-links.open{
    opacity: 1;
    transform: translateY(0);
    visibility: visible;
    pointer-events: auto;
  }
  .nav-links a{
    padding: 16px 2px;
    border-bottom: 1px solid var(--line-dark);
    width: 100%;
    font-size: .92rem;
  }
  /* Seven items plus the CTA can exceed a short phone screen in landscape. */
  .nav-links{ overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .nav-links a.nav-shop{
    font-size: 1.05rem;
    color: var(--white);
    border-bottom-color: rgba(179,18,45,.55);
  }
  .nav-cta{ margin: 18px 0 0; text-align: center; justify-content: center; }
  .nav-toggle{ display: flex; }
}

/* ---------- mobile shop bar ----------
   Added 2026-09-18. Phone-only, and it only appears once the hero has scrolled
   past, so it never covers the opening statement. Deliberately the ONLY extra
   shop affordance on mobile: the header already carries a labelled Menu button,
   and stacking a second header link on top of this would just be clutter.
   Left in normal DOM order at the end of <body> and focus is never forced into
   it, so keyboard and screen-reader order stay predictable. */
.shop-bar{
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 90;
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 11px 18px calc(11px + env(safe-area-inset-bottom));
  background: rgba(10,10,10,.94);
  backdrop-filter: blur(8px);
  border-top: 1px solid rgba(217,165,49,.34);
  transform: translateY(105%);
  transition: transform .26s ease;
}
.shop-bar.visible{ transform: translateY(0); }
.shop-bar-text{
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  min-width: 0;
}
.shop-bar-text strong{
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: .98rem;
  color: var(--white);
}
.shop-bar-text span{
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gold);
}
.shop-bar .btn{
  padding: 12px 20px;
  font-size: .72rem;
  flex-shrink: 0;
}
@media (max-width: 860px){
  .shop-bar{ display: flex; }
  /* Stop the bar sitting on top of the last line of the footer. */
  .site-footer{ padding-bottom: 96px; }
}

/* ---------- footer ---------- */
.site-footer{
  background: var(--black);
  color: var(--muted-dark);
  padding: 56px 0 28px;
  border-top: 1px solid var(--line-dark);
}
.footer-top{
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
  justify-content: space-between;
  align-items: flex-start;
  padding-bottom: 32px;
  border-bottom: 1px solid var(--line-dark);
}
.footer-brand .brand{ margin-bottom: 10px; }
.footer-brand p{
  max-width: 320px;
  font-size: .88rem;
  line-height: 1.6;
  color: var(--muted-dark);
}
.footer-links{
  display: flex;
  gap: 56px;
  flex-wrap: wrap;
}
.footer-col h4{
  font-family: var(--font-body);
  font-size: .7rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--white);
  margin-bottom: 14px;
}
.footer-col a{
  display: block;
  font-size: .86rem;
  color: var(--muted-dark);
  padding: 6px 0;
  transition: color .15s ease;
}
.footer-col a:hover{ color: var(--white); }
.footer-bottom{
  padding-top: 22px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: space-between;
  font-size: .76rem;
}

/* ---------- generic section rhythm ---------- */
.section{ padding: 96px 0; }
.section-tight{ padding: 64px 0; }

/* ---------- solo product block ----------
   Added 2026-09-17 for the single-print drops (devil girl, both cats, Vex,
   the support hoodie). The anime page's flip-card only makes sense for a
   front+back design, and the gag page's frame is scoped to gag.css, so this
   is the one shared pattern every page can use. Inherits the light/dark
   section colours already defined per page rather than setting its own. */
.solo-section{ padding: 96px 0; }
.solo-layout{
  display: grid;
  grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
  gap: 56px;
  align-items: center;
}
.solo-frame{
  position: relative;
  border: 1px solid var(--line-light);
  background: #050505;
  overflow: hidden;
}
.solo-section.dark .solo-frame,
.dark-page .solo-frame{ border-color: var(--line-dark); }
.solo-frame img{ width: 100%; display: block; }
.solo-frame .solo-tag{
  position: absolute;
  left: 0; bottom: 0;
  background: var(--accent);
  color: var(--white);
  font-family: var(--font-display);
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 7px 13px;
}
.solo-info .price{ display: block; margin: 6px 0 14px; }
@media (max-width: 860px){
  .solo-layout{ grid-template-columns: 1fr; gap: 30px; }
  .solo-frame{ max-width: 420px; }
}

/* The .specs chip row is defined per page (anime.css / gag.css) and scoped to
   parents the solo block doesn't have, so without this the specs render as one
   run-together lowercase sentence. Caught on a headless screenshot pass. */
.solo-info .specs{
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  margin-bottom: 30px;
  font-size: .78rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-weight: 700;
}
.solo-info .specs span{ opacity: .65; }
.solo-section.light .solo-info .specs{ color: var(--ink); }
.solo-section.dark .solo-info .specs,
.dark-page .solo-info .specs{ color: var(--white); }
/* Heading and blurb sizing to match the existing product cards — without this
   the new drops render visibly smaller than Goodgirl and the raccoon and read
   as second-class. */
.solo-info h2{ font-size: clamp(1.8rem, 4vw, 2.6rem); margin-bottom: 6px; }
.solo-info .price{
  font-family: var(--font-display);
  font-size: 1.4rem;
  color: var(--accent);
  margin-bottom: 20px;
}
.solo-info p.blurb{ font-size: 1.02rem; line-height: 1.7; margin-bottom: 22px; }

/* ---------- product card (shared) ----------
   Added 2026-09-18 for the Shop All page and the home page's featured strip.
   One definition, two users — do not fork a second copy into home.css. */
.p-card{
  display: flex;
  flex-direction: column;
  background: #ffffff;
  border: 1px solid var(--line-light);
  overflow: hidden;
  transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}
.p-card:hover{
  transform: translateY(-5px);
  box-shadow: 0 20px 44px rgba(0,0,0,.16);
  border-color: rgba(179,18,45,.42);
}
.p-card.is-hidden{ display: none; }

.p-media{
  position: relative;
  background: #050505;
  aspect-ratio: 1 / 1;
  overflow: hidden;
}
.p-media img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .5s ease;
}
.p-card:hover .p-media img{ transform: scale(1.035); }

/* ---------- front/back flip on the card ----------
   Added 2026-09-18 at Lycan's request: the three front+back designs flip to
   the back print on hover, so a visitor sees both sides without leaving for
   Etsy. Hover does it on a mouse; js/flip.js adds tap and keyboard for touch,
   which never holds :hover reliably.
   The chip and flag deliberately sit OUTSIDE .p-flip-inner so they stay put
   and readable while the artwork turns. */
.p-flip{ perspective: 1200px; }
.p-flip-inner{
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transition: transform .6s cubic-bezier(.2,.7,.2,1);
}
.p-card:hover .p-flip .p-flip-inner,
.p-flip.flipped .p-flip-inner{ transform: rotateY(180deg); }
.p-face{
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  overflow: hidden;
  background: #050505;
}
.p-back{ transform: rotateY(180deg); }
/* The zoom-on-hover and a 3D flip fight each other — the scale is applied to
   the same element being rotated and makes the turn wobble. Flip cards keep
   the flip, plain cards keep the zoom. */
.p-card:hover .p-flip img{ transform: none; }
/* No third badge: the chip (top-left) and the "Front + Back" flag
   (bottom-right) already say everything, and a 170px card at two-up on a
   phone cannot carry more furniture than that. */
.p-chip{
  position: absolute;
  top: 12px; left: 12px;
  background: rgba(10,10,10,.82);
  color: var(--white);
  font-family: var(--font-body);
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  padding: 6px 11px;
  backdrop-filter: blur(3px);
}
/* Bottom-right, not top-right: at two-up on a phone the card is narrow enough
   that a top-right flag collided with the category chip. Caught on a headless
   phone screenshot, not by Lycan. */
.p-flag{
  position: absolute;
  bottom: 12px; right: 12px;
  background: var(--gold);
  color: #1a1206;
  font-family: var(--font-display);
  font-size: .6rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 6px 10px;
}
.p-body{
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 20px 20px 22px;
}
.p-name{
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 1.3rem;
  line-height: 1.02;
  color: var(--ink);
  margin: 0 0 8px;
  font-weight: 400;
}
.p-price{
  font-family: var(--font-display);
  font-size: 1.12rem;
  color: var(--accent);
  margin-bottom: 11px;
}
.p-blurb{
  font-size: .87rem;
  line-height: 1.55;
  color: var(--muted-light);
  margin-bottom: 18px;
}
.p-buy{
  margin-top: auto;
  width: 100%;
  justify-content: center;
  padding: 13px 18px;
  font-size: .74rem;
}
@media (max-width: 620px){
  .p-body{ padding: 15px 14px 17px; }
  .p-name{ font-size: 1.08rem; }
  .p-price{ font-size: 1rem; }
  .p-blurb{ display: none; }   /* keep two-up cards scannable on a phone */
  .p-buy{ padding: 12px 10px; font-size: .68rem; letter-spacing: .07em; }
  /* At two-up the card is ~170px wide and "Gag & Cartoon" at full size nearly
     spanned it. Shrink the tags rather than truncate the category name. */
  .p-chip{ font-size: .54rem; letter-spacing: .1em; padding: 5px 8px; top: 9px; left: 9px; }
  .p-flag{ font-size: .54rem; letter-spacing: .1em; padding: 5px 8px; bottom: 9px; right: 9px; }
}

/* ---------- signup section (Brevo embedded form) ----------
   Added 2026-09-17. The promo bar can no longer hold the form inline because a
   visible reCAPTCHA is a ~78px widget, so the bar links down here instead.
   Brevo's markup is embedded verbatim so their JS, captcha and inline success
   and error messages keep working; everything below is override-only styling so
   it reads as part of this site rather than a pasted widget. */
.signup-section{
  background: var(--black);
  color: var(--white);
  padding: 92px 0;
  border-top: 1px solid var(--line-dark);
}
/* One enclosing panel so the offer and the email field read as a single
   thing. Lycan's note, and he was right: heading left, box right, nothing
   tying them together meant people could scroll past the 10% entirely. */
.signup-section .wrap{ display: block; }
.signup-panel{
  position: relative;
  border: 1px solid var(--gold);
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(217,165,49,.10) 0%, rgba(217,165,49,0) 55%),
    linear-gradient(180deg, #151317 0%, #0d0c0f 100%);
  box-shadow: 0 0 0 1px rgba(217,165,49,.16), 0 24px 60px -28px var(--gold-glow);
  padding: 54px 52px 50px;
}
.signup-panel::before{
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(240,195,82,.07) 50%, transparent 62%);
}
.signup-badge{
  position: absolute;
  top: 0; left: 52px;
  transform: translateY(-50%);
  background: linear-gradient(180deg, var(--gold-bright) 0%, var(--gold) 100%);
  color: #1a1206;
  font-family: var(--font-display);
  font-size: .78rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  padding: 9px 18px;
  box-shadow: 0 6px 18px -8px var(--gold-glow);
}
.signup-grid{
  display: grid;
  grid-template-columns: minmax(0,1fr) minmax(0,440px);
  gap: 56px;
  align-items: center;
}
.signup-copy .eyebrow{ color: var(--gold) !important; }
.signup-copy h2{ font-size: clamp(1.9rem, 4vw, 2.7rem); margin: 6px 0 14px; }
.signup-copy p{ font-size: 1rem; line-height: 1.7; color: var(--muted-dark); max-width: 46ch; }

/* --- Brevo overrides. Their embed ships its own <style>; these win on
       specificity without touching their HTML. --- */
.signup-form .sib-form{ padding: 0 !important; background: transparent !important; }
.signup-form #sib-container{
  background: transparent !important;
  border: 1px solid var(--line-dark) !important;
  padding: 28px !important;
  max-width: none !important;
}
.signup-form .sib-form-block__button{
  background: var(--accent) !important;
  color: var(--white) !important;
  font-family: var(--font-display) !important;
  font-size: 14px !important;
  font-weight: 700 !important;
  letter-spacing: .08em !important;
  text-transform: uppercase !important;
  border: 0 !important;
  border-radius: 0 !important;
  padding: 14px 24px !important;
}
.signup-form .sib-form-block__button:hover{ background: var(--accent-bright) !important; }
.signup-form .entry__field{
  background: #ffffff !important;
  border: 0 !important;
  border-radius: 0 !important;
}
.signup-form .entry__label,
.signup-form .sib-text-form-block p,
.signup-form .entry__specification{ color: var(--muted-dark) !important; }
/* Brevo's duplicate heading and subtitle are removed from the MARKUP in
   index.html, not hidden here. A CSS rule that hid bare .sib-form-block also
   hid the submit button, because the button's wrapper carries the same class
   and nothing else. Lycan caught it live: an email field with no button and no
   way to know you had to press Enter. Do not reintroduce that rule. */
.signup-form #sib-container{ padding: 26px !important; }
.signup-form .entry__label{
  color: var(--white) !important;
  font-family: var(--f-mono, inherit);
  font-size: 12px !important;
  letter-spacing: .12em !important;
  text-transform: uppercase !important;
  font-weight: 700 !important;
}
.signup-form .entry__specification{ font-size: 12px !important; opacity: .7; }
.signup-form .sib-form-message-panel{ margin-bottom: 14px !important; }
.signup-form form,
.signup-form .sib-form-container{ padding: 0 !important; }
@media (max-width: 900px){
  .signup-section .wrap{ grid-template-columns: 1fr; gap: 32px; }
}
/* The input sits on white but inherited the section's white text, so anything
   typed was invisible. Caught live by Lycan. Pin both the text and the
   placeholder rather than relying on inheritance. */
.signup-form .entry__field input,
.signup-form input.input,
.signup-form input[type="text"],
.signup-form input[type="email"]{
  color: #16151a !important;
  background: #ffffff !important;
  -webkit-text-fill-color: #16151a !important;
}
.signup-form .entry__field input::placeholder,
.signup-form input::placeholder{ color: #8a8590 !important; opacity: 1 !important; }
/* Typed text was white on a white input because it inherited the dark section's
   colour. Caught live by Lycan. Pin text and placeholder explicitly. */
.signup-form .entry__field input,
.signup-form input.input,
.signup-form input[type="text"],
.signup-form input[type="email"]{
  color: #16151a !important;
  background: #ffffff !important;
  -webkit-text-fill-color: #16151a !important;
}
.signup-form .entry__field input::placeholder,
.signup-form input::placeholder{ color: #8a8590 !important; opacity: 1 !important; }
.signup-form #sib-container{ border-color: rgba(217,165,49,.32) !important; }
@media (max-width: 900px){
  .signup-panel{ padding: 46px 24px 38px; }
  .signup-badge{ left: 24px; }
  .signup-grid{ grid-template-columns: 1fr; gap: 30px; }
}

/* ---------- reCAPTCHA mobile fit (THE sideways-scroll bug) ----------
   Added 2026-09-18. Google's reCAPTCHA v2 checkbox is a hard 304x78px iframe.
   Inside this panel on a phone that did not fit, and because it is a real
   layout box it dragged the whole document wider than the viewport: measured
   443px against a 390px screen. Result was a page you could scroll sideways,
   a white strip down the side, and the "Get 10% off your first order" heading
   cut in half.

   The widget is scaled down and the wrapper clipped to the scaled footprint so
   the layout box shrinks with it. js/captcha-fit.js sets --cap-scale from the
   real measured width; the 1 here is the no-JS fallback, which combined with
   html{overflow-x:clip} degrades to "slightly clipped" rather than "page is
   broken". Do not scale the image-challenge popup — Google appends that to
   document.body, outside this container, and transforming it is a known source
   of positioning bugs. Full reasoning in js/captcha-fit.js. */
.signup-form .sib-captcha .form__label-row{
  width: calc(304px * var(--cap-scale, 1));
  height: calc(78px * var(--cap-scale, 1));
  overflow: hidden;
}
.signup-form .sib-captcha #sib-captcha{
  transform: scale(var(--cap-scale, 1));
  transform-origin: 0 0;
  width: 304px;
  height: 78px;
}
/* The email field had picked up the captcha's 304px as its width. Pin it fluid
   so it fills whatever the panel actually gives it. */
.signup-form .sib-input .entry__field,
.signup-form .sib-input input.input{
  width: 100% !important;
  max-width: 100% !important;
}
/* Nothing inside a third-party embed gets to set its own minimum width —
   EXCEPT the captcha subtree. Squashing that iframe to the container width
   does not make the widget responsive, it just clips Google's own content
   inside the frame (the logo and the "I'm not a robot" label get cut off).
   The captcha has to stay at its native 304px and be scaled instead. Measured:
   with the blanket rule applied the iframe rendered at 250px with its right
   edge cut. */
.signup-form,
.signup-form *:not(.sib-captcha *):not(.sib-captcha){ min-width: 0; max-width: 100%; }
.signup-form .sib-captcha #sib-captcha,
.signup-form .sib-captcha #sib-captcha > div,
.signup-form .sib-captcha #sib-captcha iframe{
  width: 304px !important;
  max-width: none !important;
  min-width: 304px !important;
}

/* Tighter gutters on a phone. 28px each side is a lot of a 390px screen, and
   every pixel reclaimed here is a pixel the captcha does not have to be scaled
   down by. */
@media (max-width: 620px){
  .wrap{ padding: 0 18px; }
  .signup-section{ padding: 64px 0; }
  .signup-panel{ padding: 40px 16px 32px; }
  .signup-badge{ left: 16px; }
  .signup-form #sib-container{ padding: 18px !important; }
}
