:root {
  --bg: #FAF5EA;
  --bg-alt: #EFE1C6;
  /* Off-white band for a section that would otherwise sit on the same tone as
     the card caption plates and swallow them (see .bestsellers). Deliberately
     a shade off --surface so the card panels still lift off it, and off --bg
     so the band still reads as its own section. */
  --bg-soft: #F6F1E7;
  --surface: #FFFBF3;
  --text: #3B2A1D;
  --text-muted: #8B7256;
  --ink: #6B4226;
  --ink-soft: #7A5A3A;
  --btn: #4A3320;
  --btn-hover: #5E4128;
  --border: #E6D9C0;
  --on-hero: #FBF3E4;
  --radius: 0px;
  --font-head: "Playfair Display", serif;
  --font-body: "Poppins", sans-serif;
}

* { box-sizing: border-box; }
/* Justified body copy must never be hyphenated or split mid-word — with the
   narrow columns on mobile that reads as broken words rather than tidy text. */
.policy-block p, .sobre-banner-text p, .processo-content p {
  hyphens: none;
  -webkit-hyphens: none;
  overflow-wrap: normal;
  word-break: normal;
}
/* ---------- Overscroll colours ----------
   Pull-to-refresh is deliberately left enabled (overscroll-behavior used to be
   "none" here, which is what stopped it working).
   The two ends of the page need different colours behind the rubber band: the
   page's own colour at the top, the footer's at the bottom. A single
   background-color can't do that, so the top colour is painted as a background
   IMAGE extended 100vh above the document, leaving background-color to show
   through only past the bottom edge. Each page sets --page-top to whatever its
   own first screen is; --page-end always matches the footer. */
html {
  scroll-behavior: smooth;
  --page-top: var(--bg);
  --page-end: #131313;
  background-color: var(--page-end);
  background-image: linear-gradient(var(--page-top), var(--page-top));
  background-repeat: no-repeat;
  background-size: 100% calc(100% + 100vh);
  background-position: 0 -100vh;
}
/* The home page opens on the dark hero photo, not on the cream ground. */
html.page-hero { --page-top: #1a1209; }

/* ---------- Scrollbar ---------- */
/* Scrollbar hidden site-wide (the page still scrolls normally). */
html { scrollbar-width: none; -ms-overflow-style: none; }
::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* Nothing on the site should be selectable or show a grey tap flash — that
   flash is what made images look like they turned white on an accidental
   touch while scrolling. Form fields stay selectable, or you couldn't type. */
* {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
}
input, textarea, select {
  user-select: text;
  -webkit-user-select: text;
}

/* ---------- Never zoom on focus ----------
   iOS zooms the page whenever a focused field computes to under 16px, and it
   ignores user-scalable=no, so 16px is the only thing that actually stops it.
   The plain "input" selector this used to rely on lost to every class rule in
   the file (.checkout-input was 13px — that is why the coupon box kept zooming
   however many times it was "fixed"). !important is deliberate: it is the only
   way to guarantee no future rule can quietly reintroduce the zoom. If a field
   needs to LOOK smaller, scale its box with padding, never its font-size. */
input, textarea, select,
.checkout-input, .account-field input, .account-field select,
.search-bar input, .newsletter-form input, .contato-field input, .contato-field textarea {
  font-size: 16px !important;
}

img { -webkit-user-drag: none; user-select: none; pointer-events: none; }

/* ---------- Touch devices get no hover state ----------
   Without this guard a tap leaves :hover stuck on whatever was touched, so an
   image brushed mid-scroll keeps its hover treatment until you tap elsewhere.
   Every hover rule in this file is scoped to real pointers only. */
@media (hover: none) {
  * { -webkit-tap-highlight-color: transparent !important; }
}

/* Locks the page behind an open drawer/modal so only the panel scrolls. */
/* iOS Safari ignores overflow:hidden on <body> alone, so the lock has to go on
   <html> too, and touch-action stops the rubber-band drag that gets through
   anyway. The open panel re-enables its own scrolling below. */
html.no-scroll, body.no-scroll { overflow: hidden; touch-action: none; }
.cart-drawer, .wishlist-drawer, .pd-overlay, .checkout-overlay, .quiz-overlay { touch-action: pan-y; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-weight: 300;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  opacity: 0;
  transition: opacity 0.18s ease;
}
body.page-loaded { opacity: 1; }

.container {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 24px;
}

h1, h2, h3 { font-family: var(--font-head); font-weight: 500; margin: 0; letter-spacing: 0.2px; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
button { font-family: var(--font-body); }

/* ---------- Scroll reveal ---------- */
/* Nothing is hidden by CSS alone. js/main.js adds .rise to the elements it is
   going to animate, so a page whose script fails — or a visitor with reduced
   motion — simply sees everything, instead of the blank sections the previous
   "opacity:0 on .reveal" left behind. */
.rise { opacity: 0; transform: translateY(24px); }
.reveal.in-view .rise,
.reveal.in-view.rise {
  opacity: 1;
  transform: none;
  transition: opacity 0.72s cubic-bezier(0.22, 0.7, 0.3, 1),
              transform 0.72s cubic-bezier(0.22, 0.7, 0.3, 1);
}
@media (prefers-reduced-motion: reduce) {
  .rise { opacity: 1; transform: none; transition: none; }
}

/* ---------- Header ---------- */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  background: transparent;
  transition: background 0.35s ease;
}
/* No backdrop-filter here on purpose: it promotes the fixed header to its own
   composited layer, and iOS Safari can strand that layer mid-screen after a
   rubber-band/pull-to-refresh gesture instead of repainting it back to the
   top. The background is 98% opaque, so the blur was invisible regardless. */
.site-header.scrolled {
  background: rgba(250, 245, 234, 0.98);
}

/* Pages without a full-bleed hero pin the header with sticky rather than
   fixed. Sticky stays in normal document flow, so iOS Safari has no detached
   layer to strand mid-screen after an overscroll gesture — which is the bug
   removing backdrop-filter alone didn't fully solve. index.html keeps
   position:fixed because its header has to float transparently over the hero.
   Since a sticky header occupies its own space, the 84px .page-offset that
   compensated for the fixed one has to come off, or it double-counts. */
.site-header-static { position: sticky; }
.site-header-static ~ .page-offset { padding-top: 0; }

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 84px;
}

/* Default text is light because the header is transparent over the (dark) hero photo;
   once scrolled (or on pages with no hero, which start "scrolled") it sits on the new
   light theme instead, so it flips to the dark palette. */
.logo {
  font-family: var(--font-head);
  font-size: 21px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--on-hero);
  transition: color 0.2s;
}
.logo span { color: inherit; font-weight: 500; opacity: 0.6; }

.main-nav { display: flex; gap: 34px; }
/* Search/account only fold into the nav dropdown on mobile (see the
   860px media query) — on desktop they stay as icons in .header-actions. */
.mobile-nav-action, .main-nav-divider { display: none; }
.main-nav a {
  font-size: 11.5px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: rgba(251, 243, 228, 0.85);
  transition: color 0.2s;
}
.main-nav a:hover { color: var(--on-hero); opacity: 0.6; }

.header-actions { display: flex; align-items: center; gap: 4px; }

.icon-btn {
  background: none;
  border: none;
  color: var(--on-hero);
  cursor: pointer;
  position: relative;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: opacity 0.2s;
}
.icon-btn:hover { opacity: 0.6; }
.icon-btn.active { opacity: 0.6; }

.site-header.scrolled .logo { color: var(--text); }
.site-header.scrolled .main-nav a { color: var(--text-muted); }
.site-header.scrolled .main-nav a:hover { color: var(--text); opacity: 1; }
.site-header.scrolled .icon-btn { color: var(--text); }

.badge-count {
  position: absolute;
  top: 0;
  right: 0;
  background: var(--ink);
  color: var(--on-hero);
  font-size: 10px;
  font-weight: 500;
  min-width: 16px;
  height: 16px;
  border-radius: 50%;
  align-items: center;
  justify-content: center;
  display: none;
  padding: 0 3px;
}

.menu-btn { display: none; }

/* ---------- Language toggle ---------- */
/* Both languages on screen, with a knob that slides to the active one. A single
   letter that swapped on press never said which language you were about to get
   — this says what you are reading and what you can switch to at the same time. */
.lang-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 0;
  border: 1px solid currentColor;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  cursor: pointer;
  overflow: hidden;
  line-height: 1;
  -webkit-tap-highlight-color: transparent;
}
.lang-opt {
  position: relative;
  z-index: 1;
  width: 30px;
  padding: 6px 0;
  text-align: center;
  font-family: var(--font-body);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.6px;
  color: currentColor;
  opacity: 0.5;
  transition: opacity 0.25s ease, color 0.25s ease;
}
/* The active half is the one the knob is under. */
.lang-toggle:not(.is-en) .lang-opt[data-lang="pt"],
.lang-toggle.is-en .lang-opt[data-lang="en"] { opacity: 1; }

/* Inset by the same 2px on BOTH sides of its half, so the knob is centred under
   the letter it is under. At a fixed 28px it was flush against one edge — which
   is why it read as sitting off to the right on EN. Its width is half the track
   less both insets; the travel is that width plus one inset, which lands it
   exactly under the second letter. */
.lang-knob {
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: 2px;
  width: calc(50% - 4px);
  border-radius: 999px;
  background: currentColor;
  transition: transform 0.3s cubic-bezier(0.34, 1.3, 0.5, 1);
}
.lang-toggle.is-en .lang-knob { transform: translateX(calc(100% + 4px)); }
/* The letter sitting on the knob has to invert, or it disappears into it. */
.lang-toggle:not(.is-en) .lang-opt[data-lang="pt"],
.lang-toggle.is-en .lang-opt[data-lang="en"] { color: var(--bg); mix-blend-mode: normal; }

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

/* ---------- Overflow ("more") menu: search + account tucked away on mobile ---------- */
.more-menu { position: relative; display: flex; align-items: center; }
.more-btn { display: none; }
.more-menu-panel { display: flex; align-items: center; gap: 4px; }
.more-menu-item {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  color: var(--on-hero);
  transition: opacity 0.2s;
}
.more-menu-item:hover { opacity: 0.6; }
.more-menu-item span { display: none; }
.site-header.scrolled .more-menu-item { color: var(--text); }

/* ---------- Search bar ---------- */
.search-bar {
  max-height: 0;
  overflow: hidden;
  background: rgba(250, 245, 234, 0.98);
  border-bottom: 1px solid transparent;
  transition: max-height 0.3s ease, border-color 0.3s ease;
}
.search-bar.open { max-height: 84px; border-color: var(--border); }
.search-bar .container { display: flex; align-items: center; gap: 14px; padding-top: 18px; padding-bottom: 18px; }
.search-bar input {
  flex: 1;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  padding: 8px 2px;
  outline: none;
}
.search-bar input:focus { border-color: var(--ink); }
.search-bar button { background: none; border: none; color: var(--text-muted); font-size: 22px; line-height: 1; cursor: pointer; }
.search-bar button:hover { color: var(--text); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 15px 36px;
  border-radius: var(--radius);
  font-size: 11.5px;
  letter-spacing: 2px;
  text-transform: uppercase;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.btn-outline-gold { background: transparent; border: 1px solid var(--on-hero); color: var(--on-hero); }
.btn-outline-gold:hover { background: var(--on-hero); color: var(--text); }

.btn-solid-cream { background: var(--on-hero); border: 1px solid var(--on-hero); color: var(--text); }
.btn-solid-cream:hover { background: transparent; color: var(--on-hero); }

/* Same shape as btn-outline-gold, but for use on light surfaces (cards, not hero photos). */
.btn-outline-dark { background: transparent; border: 1px solid var(--btn); color: var(--btn); }
.btn-outline-dark:hover { background: var(--btn); color: #fff; }

.btn-primary { background: var(--btn); color: var(--on-hero); font-weight: 400; }
.btn-primary:hover { background: var(--btn-hover); }
.btn-primary.disabled { opacity: 0.35; pointer-events: none; }

.btn-small {
  padding: 10px 20px;
  font-size: 10.5px;
  letter-spacing: 1.6px;
  border: 1px solid var(--btn);
  color: var(--btn);
  background: transparent;
  border-radius: var(--radius);
}
.btn-small:hover { background: var(--btn); color: var(--on-hero); }
.btn-block { width: 100%; }

/* The featured card's button now lives on the white flip back-face like every
   other card's, so it uses the default ink styling — the old white-on-photo
   override would have made it invisible there. */

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.hero-media {
  position: absolute;
  inset: -8% -8%;
  background: url("../img/hero-mobile-bg.png") center 30% / cover no-repeat;
  /* Promoted to its own compositor layer. Without translateZ the parallax
     transform repaints a background larger than the viewport on every frame,
     which is what the stutter was. */
  will-change: transform;
  transform: translateZ(0);
  backface-visibility: hidden;
}
/* Left-to-right fade instead of a flat top-to-bottom scrim: keeps the
   bottle photography clear on the right while still grounding the text
   on the left, where the source photo is already mostly plain backdrop. */
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgba(20, 14, 8, 0.58) 0%, rgba(20, 14, 8, 0.32) 32%, rgba(20, 14, 8, 0.06) 55%, rgba(20, 14, 8, 0) 70%);
}

.hero-inner { position: relative; z-index: 1; max-width: 560px; padding-top: 80px; color: var(--on-hero); }
.hero-inner > * { opacity: 0; transform: translateY(16px); animation: hero-rise 0.85s cubic-bezier(0.2, 0.6, 0.2, 1) forwards; }
.hero-inner .eyebrow { animation-delay: 0.1s; }
.hero-inner h1 { animation-delay: 0.25s; }
.hero-inner .hero-text { animation-delay: 0.4s; }
.hero-inner .hero-ctas { animation-delay: 0.55s; }
@keyframes hero-rise { to { opacity: 1; transform: translateY(0); } }

.eyebrow {
  color: inherit;
  opacity: 0.7;
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 4px;
  margin-bottom: 18px;
  display: block;
}
.hero h1 { color: var(--on-hero); font-weight: 400; font-size: clamp(34px, 5.4vw, 58px); line-height: 1.15; margin-bottom: 22px; font-family: var(--font-head); font-style: italic; }
.hero h1 em { color: inherit; font-style: italic; }
.hero-text { color: rgba(251, 243, 228, 0.85); font-size: 16px; max-width: 420px; margin-bottom: 38px; letter-spacing: 0.2px; }
.hero-ctas { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }

/* ---------- Section head (shared) ---------- */
.section-head { text-align: center; max-width: 520px; margin: 0 auto 46px; }
.section-head h2 { font-weight: 400; font-size: 30px; margin-bottom: 10px; }
.section-head p { color: var(--text-muted); font-size: 13.5px; letter-spacing: 0.3px; }

/* ---------- Featured / "Nossa Seleção" ---------- */
.featured { padding: 110px 0 100px; }
.featured-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; }

/* ---------- Brand story ---------- */
.historia { padding: 120px 0; }
.historia-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 70px; align-items: center; }
.historia-media img { border-radius: var(--radius); width: 100%; height: 480px; object-fit: cover; object-position: 70% center; }
.historia-content h2 { font-weight: 400; font-size: 30px; margin-bottom: 22px; }
.historia-content p { color: var(--text-muted); font-size: 15px; line-height: 1.85; margin-bottom: 22px; max-width: 460px; }

.sobre-stats { display: flex; gap: 40px; }
.sobre-stats div { display: flex; flex-direction: column; gap: 4px; }
.sobre-stats strong { font-family: var(--font-head); font-weight: 400; font-size: 21px; color: var(--text); }
.sobre-stats span { font-size: 10.5px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 1px; }

/* ---------- Sobre: hero banner ---------- */
.sobre-banner-media { position: relative; height: 64vh; min-height: 440px; max-height: 620px; overflow: hidden; }
.sobre-banner-media img { width: 100%; height: 100%; object-fit: cover; object-position: 70% center; }

/* ---------- Sobre banner motion ----------
   A slow drift across the photo and a staggered rise on the text, so the top
   of the page has some life instead of landing as a flat still. The drift
   alternates rather than restarting, so it never jumps back to the start; the
   media box already clips, so the scaled photo can't spill. */
@keyframes sobre-drift {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to { transform: scale(1.09) translate3d(-1.8%, -1.2%, 0); }
}
.sobre-banner-media img {
  animation: sobre-drift 26s ease-in-out infinite alternate;
  will-change: transform;
}

/* Same curve as the home hero, but with its own keyframes: hero-rise ends at
   opacity 1, and .eyebrow is deliberately muted to 0.7 — borrowing it would
   have quietly brightened the eyebrow past its intended weight. */
@keyframes sobre-rise { to { opacity: 1; transform: translateY(0); } }
@keyframes sobre-rise-muted { to { opacity: 0.7; transform: translateY(0); } }

.sobre-banner-overlay-inner .sobre-banner-mark,
.sobre-banner-overlay-inner .eyebrow,
.sobre-banner-overlay-inner h2 {
  opacity: 0;
  transform: translateY(18px);
  animation: sobre-rise 0.9s cubic-bezier(0.2, 0.6, 0.2, 1) forwards;
}
.sobre-banner-overlay-inner .sobre-banner-mark { animation-delay: 0.15s; }
.sobre-banner-overlay-inner .eyebrow {
  animation-name: sobre-rise-muted;
  animation-delay: 0.34s;
}
.sobre-banner-overlay-inner h2 { animation-delay: 0.5s; }

@media (prefers-reduced-motion: reduce) {
  .sobre-banner-media img { animation: none; }
  .sobre-banner-overlay-inner .sobre-banner-mark,
  .sobre-banner-overlay-inner h2 { animation: none; opacity: 1; transform: none; }
  .sobre-banner-overlay-inner .eyebrow { animation: none; opacity: 0.7; transform: none; }
}
/* The gradient used to start almost clear, which left the top-left corner an
   empty wash of photo. A caption pinned up there and a touch more shade at the
   top give that corner something to hold. */
.sobre-banner-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  color: var(--on-hero);
  background: linear-gradient(180deg, rgba(38, 26, 15, 0.45) 0%, rgba(38, 26, 15, 0.22) 40%, rgba(38, 26, 15, 0.8) 100%);
}
.sobre-banner-overlay-inner {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 100%;
  padding-top: 96px;
  padding-bottom: 60px;
}
/* The original caption with its rule down the side, kept as it was. The only
   addition is a second line under it in the display face — enough to stop the
   corner reading as empty, without turning it into a graphic. */
.sobre-banner-mark {
  padding-left: 16px;
  border-left: 2px solid var(--on-hero);
}
.sobre-banner-place {
  font-size: 10.5px;
  letter-spacing: 2.6px;
  text-transform: uppercase;
  color: var(--on-hero);
  opacity: 0.9;
  margin: 0;
}
.sobre-banner-line {
  margin: 7px 0 0;
  font-family: var(--font-head);
  font-style: italic;
  font-size: 15.5px;
  line-height: 1.3;
  color: var(--on-hero);
  opacity: 0.92;
}
.sobre-banner-overlay h2 {
  font-family: var(--font-head);
  font-style: italic;
  font-weight: 400;
  color: var(--on-hero);
  font-size: clamp(28px, 4.2vw, 46px);
  line-height: 1.25;
  max-width: 660px;
}
.sobre-banner-body { padding: 72px 0 120px; }
/* Follows the "Como escolhemos" section's layout: an eyebrow, a pull quote,
   then the body copy in a contained column. Generous padding and line-height
   because the old card had the text pressed right up against its border. */
/* No card, no border, no rule under the eyebrow: the story flows straight out
   of the banner into the page instead of being boxed off from it. */
.sobre-banner-text {
  max-width: 660px;
  width: 100%;
  margin: 0 auto;
  overflow-wrap: break-word;
  padding: 0;
}
.sobre-banner-text .eyebrow { margin-bottom: 18px; }
/* Exactly as it was — centred, full width, --text — with only the side rule
   from "Como escolhemos" added. */
.sobre-banner-text .processo-quote {
  border-left: 2px solid var(--ink);
  padding-left: 20px;
  margin: 0 auto 30px;
  max-width: none;
  text-align: center;
  color: var(--text);
}
.sobre-banner-text p { color: var(--text-muted); font-size: 15px; line-height: 2; margin-bottom: 26px; text-align: justify; }
.sobre-banner-text p:last-of-type { margin-bottom: 0; }
/* The stats sit centred under the story, in the same 660px column and with
   the card's own horizontal padding, so the three figures line up with the
   text above them instead of drifting to one side. */
.sobre-banner-body .sobre-stats {
  max-width: 660px;
  width: 100%;
  margin: 40px auto 0;
  box-sizing: border-box;
  padding: 30px 0 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  text-align: center;
}
.sobre-banner-body .sobre-stats div { align-items: center; }

/* ---------- Processo (Como escolhemos) ---------- */
.processo { padding: 120px 0; background: var(--bg-alt); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.processo-inner { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: 80px; align-items: center; }
.processo-media { position: relative; }
.processo-media::before {
  content: "";
  position: absolute;
  inset: 20px -20px -20px 20px;
  border: 1px solid var(--ink);
  border-radius: 12px;
  z-index: 0;
}
.processo-media img { position: relative; z-index: 1; width: 100%; height: 540px; object-fit: cover; border-radius: 12px; }
.processo-quote {
  font-family: var(--font-head);
  font-style: italic;
  font-size: 21px;
  line-height: 1.5;
  color: var(--ink);
  border-left: 2px solid var(--ink);
  padding-left: 20px;
  margin: 16px 0 28px;
  max-width: 440px;
}
.processo-content h2 { font-weight: 400; font-size: 28px; margin-bottom: 20px; max-width: 460px; }
.processo-content p { color: var(--text-muted); font-size: 15px; line-height: 1.85; margin-bottom: 20px; max-width: 460px; text-align: justify; }
.processo-content p:last-of-type { margin-bottom: 0; }

/* ---------- Best sellers carousel ---------- */
/* Off-white rather than --bg-alt: the cards' caption plates are --bg-alt, so
   on that ground the plate and its border vanished into the section. */
.bestsellers { padding: 100px 0 90px; background: var(--bg-soft); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.carousel {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.carousel::-webkit-scrollbar { display: none; }
.carousel-track { display: flex; gap: 26px; padding: 44px 24px 12px; width: max-content; margin: 0 auto; }
.carousel-card {
  position: relative;
  scroll-snap-align: start;
  width: 270px;
  /* Photo (3/4 of 270px) plus the caption plate. It was 510px, which left a
     tall band of empty plate under the price now the front is one panel. */
  min-height: 452px;
  flex: 0 0 auto;
  cursor: pointer;
  perspective: 1400px;
  transition: transform 0.3s;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) and (pointer: fine) {
  .carousel-card:hover { transform: translateY(-2px); }
}
.carousel-end-card {
  scroll-snap-align: start;
  width: 270px;
  /* Photo (3/4 of 270px) plus the caption plate. It was 510px, which left a
     tall band of empty plate under the price now the front is one panel. */
  min-height: 452px;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  border: 1px dashed var(--border);
  border-radius: 12px;
  color: var(--text);
  text-align: center;
  font-size: 12.5px;
  letter-spacing: 1px;
  text-transform: uppercase;
  transition: border-color 0.2s, color 0.2s;
}
@media (hover: hover) and (pointer: fine) {
  .carousel-end-card:hover { border-color: var(--text); }
}

.carousel-controls { display: flex; justify-content: flex-end; gap: 10px; margin-top: 6px; }
.carousel-controls button {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  font-size: 18px;
  cursor: pointer;
  transition: all 0.2s;
}
.carousel-controls button:hover { border-color: var(--text); }

/* ---------- Colecao ---------- */
.colecao { padding: 0 0 100px; }

.colecao-banner {
  position: relative;
  padding: 90px 0 64px;
  margin-bottom: 56px;
  background: url("../img/hero-mobile-bg.png") center 30% / cover no-repeat;
  overflow: hidden;
}
.colecao-banner::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(38, 26, 15, 0.36) 0%, rgba(38, 26, 15, 0.54) 55%, rgba(38, 26, 15, 0.76) 100%);
}
.colecao-banner .section-head { position: relative; z-index: 1; margin-bottom: 0; }
.colecao-banner .section-head h2 { color: var(--on-hero); }
.colecao-banner .section-head p { color: rgba(251, 243, 228, 0.82); }

.filters {
  display: flex;
  justify-content: center;
  gap: 28px;
  flex-wrap: wrap;
  margin-bottom: 48px;
}
.filter-btn {
  background: none;
  border: none;
  border-bottom: 1px solid transparent;
  color: var(--text-muted);
  padding: 4px 0;
  border-radius: 0;
  font-size: 11.5px;
  letter-spacing: 1.6px;
  font-family: var(--font-body);
  cursor: pointer;
  text-transform: uppercase;
  transition: all 0.2s;
}
.filter-btn:hover { color: var(--text); }
.filter-btn.active { color: var(--text); border-color: var(--text); font-weight: 500; }

.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 26px;
}

/* ---------- Perfume card ----------
   One shared structure for .product-card / .carousel-card / .featured-card
   (see perfumeCardTemplate() in js/main.js). The card flips: front is the
   bottle with name and price under it, back is the notes and the buy button.
   The front stays in normal flow and sets the height; the back is absolutely
   positioned on top of it, pre-rotated, and hidden by backface-visibility. */
.product-card, .carousel-card, .featured-card { display: block; cursor: pointer; }

/* Flex so .flip-inner stretches to the card's min-height (the carousel sets
   one); otherwise the absolutely-positioned back face would only cover as far
   down as the front's content reaches. */
.flip-card { perspective: 1400px; display: flex; flex-direction: column; }
.flip-inner {
  position: relative;
  flex: 1;
  transform-style: preserve-3d;
  transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.flip-card.flipped .flip-inner { transform: rotateY(180deg); }
.flip-face {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.flip-back {
  position: absolute;
  inset: 0;
  transform: rotateY(180deg);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 24px 22px;
  border-radius: 14px;
  border: 1px solid var(--border);
  background: var(--surface);
  overflow: hidden;
}
/* The back is the detail view, so it uses the full height: identity at the
   top, the olfactory pyramid filling the middle, size and price pinned to the
   bottom above the button. space-between is what stops it pooling into one
   clump with dead space underneath. */
/* Three bands: identity, scent, and the buying decision. Only the middle one
   flexes, so the price and the button land at the same height on every card in
   a row however much or little a product has to say. */
.flip-back { justify-content: flex-start; text-align: left; gap: 0; }
.flip-back-head { flex: 0 0 auto; padding-bottom: 11px; }
/* No margin-top:auto here. Pinning this block to the bottom put every spare
   pixel into ONE gap, directly between the name and the ml row, which read as
   though something was missing between them. space-between on the back face
   spreads the same slack across both gaps instead, so the three bands stay
   evenly spaced whatever the product has to say. */
.flip-back-buy { flex: 0 0 auto; padding-top: 12px; }
.flip-back-brand {
  display: block;
  font-size: 9.5px;
  letter-spacing: 2.2px;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 6px;
}
.flip-back-name {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 18px;
  line-height: 1.25;
  color: var(--text);
  margin: 0 0 6px;
}
.flip-back-family {
  display: block;
  font-size: 9.5px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--text-muted);
}
/* The band takes the leftover height and centres what is in it. A product
   with a full pyramid fills it exactly, so the name sits close to it and the
   ml row close beneath. A product with only one line of description — because
   its olfactory notes have never been filled in — keeps that line centred in a
   roomier panel instead of pushing a blank gap between the name and the size.
   Either way the gaps AROUND the band stay small and equal. */
.flip-back-notes {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 9px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 13px 0;
}
/* Nothing to say about this one: the rules would otherwise sit on top of each
   other as a stray double line. */
.flip-back-notes:empty { border: 0; padding: 0; }
.flip-note-row { display: flex; gap: 10px; align-items: baseline; }
.flip-note-label {
  flex: 0 0 46px;
  font-size: 8.5px;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--text-muted);
}
.flip-note-value { flex: 1; font-size: 11.5px; line-height: 1.5; color: var(--text); }
.flip-back-fallback {
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--text-muted);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.flip-back-meta {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  margin-bottom: 13px;
}
.flip-back-price-block { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.flip-back-price-block .campaign-until { text-align: left; margin-top: 2px; }
.flip-back-size { font-size: 10px; letter-spacing: 1.2px; text-transform: uppercase; color: var(--text-muted); }
.flip-back-price { font-size: 15px; font-weight: 500; color: var(--text); }
.flip-back-price .price-final { font-size: 15px; }
.flip-back-actions { flex: 0 0 auto; display: flex; flex-direction: column; align-items: stretch; }
.flip-back-actions .btn-small { width: 100%; }

/* The badge sits on the front face; when the card turns it would otherwise
   show through the back mirrored and unreadable. */
.flip-card.flipped .perfume-badge,
.flip-card.flipped .stock-badge,
.flip-card.flipped .wishlist-btn { opacity: 0; visibility: hidden; }
/* Nothing on the hidden face should be reachable — without this the back's
   buttons still take taps through the front while the card is face-up. */
.flip-card:not(.flipped) .flip-back { pointer-events: none; }
.flip-card.flipped .flip-front { pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  .flip-inner { transition: none; }
}

/* The front is one panel — photo and caption share a single surface, border
   and radius — rather than a bordered photo with loose text underneath. It
   also matches the back face, so the card reads as one object either way up. */
.flip-front {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--surface);
  /* Same beige as the caption plate behind the name and price, so the panel
     edge, the photo edge and the plate all read as one tone. */
  border: 1px solid var(--bg-alt);
  border-radius: 14px;
  /* Inset on three sides so the photo's own border sits clear of the panel's
     rather than doubling up against it. The caption plate below reclaims the
     full width with a negative margin. */
  padding: 8px 8px 0;
  box-shadow: 0 1px 2px rgba(59, 42, 29, 0.04);
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}

.perfume-card-media-wrap {
  position: relative;
  aspect-ratio: 3 / 4;
  border: 1px solid var(--bg-alt);
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
}

/* Skeleton: a shimmer in place of the photo until hydrateCardImages() has the
   real one decoded, so the grid never flashes empty panels on a slow phone. */
.perfume-card-media-wrap.is-loading {
  background: linear-gradient(100deg, var(--bg-alt) 30%, var(--surface) 50%, var(--bg-alt) 70%);
  background-size: 300% 100%;
  animation: card-skeleton 1.3s ease-in-out infinite;
}
.perfume-card-media-wrap.is-loading .perfume-card-media { opacity: 0; }
.perfume-card-media { transition: opacity 0.35s ease, transform 0.6s ease; }
@keyframes card-skeleton {
  from { background-position: 150% 0; }
  to { background-position: -50% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .perfume-card-media-wrap.is-loading { animation: none; }
}
/* Mouse only — see the hover note at the top of this file. The border now
   lives on the panel, not on the photo, so the hover moves with it. */
@media (hover: hover) and (pointer: fine) {
  .product-card:hover .flip-front,
  .carousel-card:hover .flip-front,
  .featured-card:hover .flip-front {
    border-color: var(--ink);
    box-shadow: 0 6px 18px rgba(59, 42, 29, 0.09);
  }
}

.perfume-card-media {
  position: absolute;
  inset: 0;
  background-image: var(--card-image, none);
  background-size: cover;
  background-position: center;
  transition: transform 0.6s ease;
}
@media (hover: hover) and (pointer: fine) {
  .product-card:hover .perfume-card-media,
  .carousel-card:hover .perfume-card-media,
  .featured-card:hover .perfume-card-media { transform: scale(1.05); }
}

/* Watermark bottle icon shown only when a product has no real photo (tone-N gradient card) */
.product-card-icon {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(251, 243, 228, 0.2);
  pointer-events: none;
}
.product-card-icon .bottle-icon { width: 42%; max-width: 110px; height: auto; }
.bottle-icon { width: 62px; height: auto; }
.product-photo { width: 100%; height: 100%; object-fit: contain; object-position: center; }

.tone-1 { background: linear-gradient(135deg, #3b2a1d, #5c4430); }
.tone-2 { background: linear-gradient(135deg, #332318, #5a4534); }
.tone-3 { background: linear-gradient(135deg, #2e2318, #4f4230); }
.tone-4 { background: linear-gradient(135deg, #3a281b, #5e4231); }
.tone-5 { background: linear-gradient(135deg, #362a1a, #5a4938); }
.tone-6 { background: linear-gradient(135deg, #2c2216, #4a3c2a); }

/* Best Seller / Novidade — only rendered when the product's own flag is set */
.perfume-badge {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 2;
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  padding: 6px 11px;
  border-radius: 3px;
  color: var(--on-hero);
}
.badge-bestseller { background: var(--ink); }
.badge-new { background: var(--text); }
.stock-badge ~ .perfume-badge, .perfume-badge ~ .stock-badge { top: 46px; }

/* Tight to the image: the name and price read as part of the card rather
   than a block floating underneath it. */
.perfume-card-body { padding: 8px 2px 0; }
.perfume-card-family {
  display: block;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1.8px;
  color: var(--text-muted);
  margin-bottom: 8px;
}
.perfume-card-name { font-family: var(--font-head); font-weight: 400; font-size: 17px; color: var(--text); margin: 0 0 6px; }
.perfume-card-desc {
  font-size: 12.5px;
  color: var(--text-muted);
  line-height: 1.65;
  margin: 0 0 14px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.perfume-card-footer { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.perfume-card-price { font-family: var(--font-body); font-weight: 500; font-size: 14.5px; color: var(--text); }
.featured-card .perfume-card-name { font-size: 19px; }
.featured-card .perfume-card-desc { font-size: 13px; -webkit-line-clamp: 3; }
.featured-card .perfume-card-price { font-size: 15.5px; }

/* The caption sits inside the panel, on its own slightly warmer ground with a
   hairline above it, so the name and price read as a plate under the bottle
   rather than as text dropped on the page. */
.flip-front .perfume-card-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  flex: 1;
  gap: 5px;
  /* Negative side/bottom margins cancel the panel's padding so the plate runs
     edge to edge under the inset photo. */
  margin: 8px -8px 0;
  padding: 12px 12px 14px;
  background: var(--bg-alt);
  /* No divider line: the photo is inset with its own border, so the strip of
     surface above the plate already separates them — and a --border rule here
     would be a darker tone than the plate and the two card edges. */
  border-radius: 0 0 13px 13px;
}
/* Clamped to two lines so the price row lands at the same height across a row
   of cards, but the name is bottom-aligned inside that reserved space — with
   top alignment a one-line title left an obvious hole above the price. */
.flip-front .perfume-card-name {
  margin: 0;
  min-height: 2.3em;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  font-family: var(--font-head);
  font-size: 16px;
  letter-spacing: 0.2px;
  line-height: 1.15;
  color: var(--text);
  overflow: hidden;
}
/* The price is the one piece of hard information here, so it gets the ink
   colour and its own weight instead of sharing the name's. Tabular figures
   keep the columns of prices lining up down the grid. */
.flip-front .perfume-card-price {
  min-height: 0;
  line-height: 1.2;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* ---------- Discount pricing ----------
   Column, not row: the live price reads first and the struck-through original
   with its -% chip sits underneath it. */
.price-discounted { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.flip-front .price-discounted { align-items: center; }
.price-was { display: flex; align-items: center; gap: 7px; }
.price-original { font-size: 12px; color: var(--text-muted); text-decoration: line-through; }
.price-final { color: var(--ink); font-weight: 500; }
.price-badge {
  font-size: 9.5px;
  letter-spacing: 0.8px;
  font-weight: 600;
  color: #fff;
  background: #8a3b2b;
  padding: 2px 6px;
  border-radius: 999px;
}
/* On the card the "was" row is secondary information, so it is set smaller and
   quieter than the live price above it rather than competing with it. */
.flip-front .price-was { gap: 6px; }
.flip-front .price-original { font-size: 11px; }
.flip-front .price-badge { font-size: 9px; padding: 1.5px 6px; }
/* pd-modal and cart rows are left-anchored (the flex axis is vertical now, so
   this is align-items, not justify-content). */
.pd-price.price-discounted, .cart-item-info .price-discounted { align-items: flex-start; }

/* ---------- Stock badge ---------- */
.stock-badge {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 2;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #fff;
  background: rgba(38, 26, 15, 0.72);
  padding: 5px 10px;
  border-radius: 3px;
}
/* Pushed down when a Best Seller/Novidade badge already occupies the
   top-left corner of the same media panel. */
.perfume-badge ~ .stock-badge { top: 46px; }
.btn-small:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-small:disabled:hover { background: transparent; color: var(--btn); }

/* ---------- Wishlist toggle on cards ---------- */
.wishlist-btn {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(38, 26, 15, 0.4);
  border: 1px solid rgba(251, 243, 228, 0.4);
  color: var(--on-hero);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s;
  z-index: 2;
}
.wishlist-btn:hover { border-color: var(--on-hero); }
.wishlist-btn.active { color: var(--on-hero); border-color: var(--on-hero); }
.wishlist-btn svg { width: 16px; height: 16px; }

/* ---------- Find Your Scent (quiz teaser) ---------- */
.quiz-teaser {
  padding: 100px 0;
  background: #fff;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  text-align: center;
}
.quiz-teaser-inner { max-width: 540px; margin: 0 auto; }
.quiz-teaser .eyebrow { color: var(--ink); opacity: 1; }
.quiz-teaser h2 { font-family: var(--font-head); font-style: italic; font-weight: 400; font-size: 30px; margin-bottom: 14px; }
.quiz-teaser-inner > p:not(.eyebrow) { color: var(--text-muted); font-size: 15px; margin-bottom: 32px; }

/* ---------- Reviews ---------- */
.reviews { padding: 100px 0; background: var(--bg-alt); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
/* Desktop keeps a static two-column grid; the duplicate cards the marquee
   needs on mobile are hidden here so they don't double the grid. */
.reviews-track { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px; background: var(--border); }
.review-card[data-clone] { display: none; }
.review-card { background: var(--surface); border: none; border-radius: var(--radius); padding: 40px; text-align: center; }
.stars { color: #d4a437; letter-spacing: 3px; margin-bottom: 16px; font-size: 14px; }
.review-card p { font-style: italic; color: var(--text); margin-bottom: 18px; font-size: 15px; line-height: 1.75; }
.review-card span { color: var(--text-muted); font-size: 12px; letter-spacing: 0.8px; text-transform: uppercase; }

/* ---------- Newsletter ---------- */
.newsletter { padding: 110px 0; }
.newsletter-inner { position: relative; max-width: 560px; margin: 0 auto; text-align: center; padding: 60px 44px; border: 1px solid var(--border); border-radius: var(--radius); }
.newsletter h2 { font-weight: 400; font-size: 26px; margin-bottom: 14px; }
.newsletter p { color: var(--text-muted); font-size: 14px; margin-bottom: 30px; }
.newsletter-form { display: flex; gap: 10px; }
.newsletter-form input {
  flex: 1;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  outline: none;
}
.newsletter-form input:focus { border-color: var(--text); }
.newsletter-note { margin-top: 16px; font-size: 12.5px; color: var(--text-muted); min-height: 16px; }

/* ---------- Contato ----------
   Dark panel section sitting directly above the (also dark) footer, so the
   page closes on one continuous dark band rather than a cream section butting
   into a dark one. Local tokens keep the dark palette in one place. */
/* Mushy's own palette and type, not the dark reference layout this section was
   first built from: cream ground, Playfair headings, ink rules and the gold
   accent that appears elsewhere on the site. Same structure — form beside a
   column of contact cards — in the shop's own voice. */
.contato {
  --ct-line: var(--border);
  --ct-label: var(--text-muted);
  --ct-accent: var(--ink);
  padding: 96px 0 104px;
  background: var(--bg-alt);
  border-top: 1px solid var(--border);
  color: var(--text);
}
.contato-grid { display: grid; grid-template-columns: 1.85fr 1fr; gap: 22px; align-items: start; }

.contato-panel {
  background: var(--surface);
  border: 1px solid var(--ct-line);
  border-radius: 14px;
  padding: 44px 42px;
}
.contato-panel h2 {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 30px;
  color: var(--text);
  margin: 0 0 8px;
}
.contato-panel-sub { color: var(--text-muted); font-size: 14.5px; margin: 0 0 32px; }

.contato-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.contato-field { margin-bottom: 20px; }
.contato-field label {
  display: block;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--ct-label);
  margin-bottom: 10px;
}
.contato-field input,
.contato-field textarea {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--font-body);
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--ct-line);
  border-radius: 8px;
  padding: 14px 16px;
  line-height: 1.5;
  transition: border-color 0.2s;
}
.contato-field textarea { resize: vertical; min-height: 140px; }
.contato-field input::placeholder,
.contato-field textarea::placeholder { color: var(--text-muted); opacity: 0.75; }
.contato-field input:focus,
.contato-field textarea:focus { outline: none; border-color: var(--ct-accent); }
.contato-panel .btn-primary { margin-top: 4px; }

.contato-aside { display: flex; flex-direction: column; gap: 14px; }
.contato-info {
  background: var(--surface);
  border: 1px solid var(--ct-line);
  border-radius: 14px;
  padding: 22px 24px;
  display: flex;
  align-items: flex-start;
  gap: 16px;
  transition: border-color 0.2s;
}
.contato-info-icon {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--bg-alt);
  border: 1px solid var(--ct-line);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ct-accent);
}
.contato-info-label {
  display: block;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--ct-label);
  margin-bottom: 7px;
}
.contato-info-value { color: var(--text); font-size: 14.5px; line-height: 1.5; margin: 0; }
.contato-info-value a { color: var(--text); }
@media (hover: hover) and (pointer: fine) {
  .contato-info-value a:hover { color: var(--ct-accent); }
  .contato-info:hover { border-color: var(--text); }
}

/* ---------- Policies page (Envio / Devoluções / Privacidade) ---------- */
.policies { padding: 90px 0 110px; }
.policies-intro { max-width: 640px; margin: 0 auto 60px; text-align: center; }
/* Fourteen bordered cards read as a form to fill in. A legal document is one
   continuous column: the sections are separated by space and a hairline, not by
   a box each, and the measure is held near 68 characters so it can be read
   rather than scanned. */
.policy-block {
  max-width: 680px;
  margin: 0 auto;
  scroll-margin-top: 110px;
  padding: 0 0 38px;
  border: 0;
  background: none;
}
.policy-block + .policy-block { border-top: 1px solid var(--border); padding-top: 38px; }
.policy-block:last-child { padding-bottom: 0; }
.policy-block h3 {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 23px;
  line-height: 1.3;
  color: var(--text);
  margin-bottom: 16px;
  text-align: left;
}
.policy-block p { color: var(--text-muted); font-size: 15px; line-height: 1.85; margin-bottom: 14px; text-align: justify; }
.policy-block p:last-child { margin-bottom: 0; }
.policy-block ul { color: var(--text-muted); font-size: 15px; line-height: 1.9; margin: 0 0 14px; padding-left: 20px; }

@media (max-width: 640px) {
  .policy-block { padding: 26px 20px; }
}

/* ---------- Contacto page ---------- */
.contacto-page { padding: 90px 0 110px; }
.contacto-card-form {
  max-width: 680px;
  margin: 0 auto 56px;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 36px 32px;
  background: var(--surface);
}
.contacto-card-form textarea {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  line-height: 1.6;
  resize: vertical;
}
.contacto-card-form textarea:focus { outline: none; border-color: var(--ink); }
.contacto-card-form .btn { margin-top: 6px; }

.faq-block { max-width: 680px; margin: 0 auto; scroll-margin-top: 100px; }
.faq-block h3 {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 22px;
  margin-bottom: 20px;
  text-align: center;
}
.faq-item {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  padding: 4px 22px;
  margin-bottom: 10px;
}
.faq-item summary {
  list-style: none;
  cursor: pointer;
  padding: 16px 28px 16px 0;
  font-size: 14.5px;
  color: var(--text);
  position: relative;
}
.faq-item summary::-webkit-details-marker { display: none; }
/* A chevron drawn from a rotated corner, so no icon font or SVG per row. */
.faq-item summary::after {
  content: "";
  position: absolute;
  right: 4px;
  top: 50%;
  width: 7px;
  height: 7px;
  border-right: 1.5px solid var(--text-muted);
  border-bottom: 1.5px solid var(--text-muted);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.25s ease;
}
.faq-item[open] summary::after { transform: translateY(-30%) rotate(-135deg); }
.faq-item p {
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.85;
  margin: 0 0 18px;
  padding-right: 10px;
}

@media (max-width: 640px) {
  .contacto-page { padding: 40px 0 60px; }
  .contacto-card-form { padding: 26px 20px; margin-bottom: 40px; }
  .faq-item { padding: 2px 18px; }
  .faq-item summary { font-size: 14px; padding: 15px 26px 15px 0; }
}

/* ---------- Footer ----------
   Sits on the dark ink ground so it reads as the end of the page rather than
   as one more cream section, and the links are grouped into named columns
   (Loja / Ajuda / Fale connosco) instead of one undifferentiated list. */
.site-footer {
  background: var(--ink);
  color: var(--on-hero);
  padding: 60px 0 26px;
}
.site-footer a { color: var(--on-hero); opacity: 0.78; transition: opacity 0.2s; }
.site-footer a:hover { opacity: 1; }
.footer-grid {
  display: grid;
  grid-template-columns: 1.1fr 0.8fr 1fr 1.2fr;
  gap: 40px;
  padding-bottom: 40px;
  border-bottom: 1px solid rgba(251, 243, 228, 0.18);
  margin-bottom: 22px;
}
.footer-col { display: flex; flex-direction: column; gap: 12px; font-size: 13px; letter-spacing: 0.3px; }
.footer-col h4 {
  font-family: var(--font-body);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 2px;
  text-transform: uppercase;
  opacity: 0.6;
  margin: 0 0 4px;
}
.footer-contact p { font-size: 12.5px; line-height: 1.75; opacity: 0.75; margin: 0 0 6px; }
.footer-contact .btn-small {
  align-self: flex-start;
  border-color: var(--on-hero);
  color: var(--on-hero);
  opacity: 1;
}
.footer-contact .btn-small:hover { background: var(--on-hero); color: var(--ink); }
.footer-brand { display: flex; flex-direction: column; gap: 18px; }
.footer-brand .logo { color: var(--on-hero); opacity: 1; }
.footer-brand .logo span { color: var(--on-hero); opacity: 0.7; }
.footer-social { display: flex; gap: 14px; }
.footer-social a {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid rgba(251, 243, 228, 0.28);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}
.footer-social a:hover { border-color: var(--on-hero); }
.footer-bottom {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 11.5px;
  letter-spacing: 0.3px;
  opacity: 0.66;
}
/* Build credit, set apart from the copyright it shares a line with. */
.footer-credit { letter-spacing: 1.4px; text-transform: uppercase; opacity: 0.85; }
.footer-credit::before { content: "· "; }

/* ---------- Cart / Wishlist Drawer ---------- */
.cart-overlay, .wishlist-overlay {
  position: fixed;
  inset: 0;
  background: rgba(38, 26, 15, 0.55);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s;
  z-index: 65;
}
.cart-overlay.open, .wishlist-overlay.open { opacity: 1; pointer-events: auto; }

.cart-drawer, .wishlist-drawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100%;
  width: 380px;
  max-width: 90vw;
  background: var(--surface);
  border-left: 1px solid var(--border);
  z-index: 70;
  transform: translateX(100%);
  transition: transform 0.3s ease;
  display: flex;
  flex-direction: column;
}
.cart-drawer.open, .wishlist-drawer.open { transform: translateX(0); }

.cart-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 22px 18px;
  border-bottom: 1px solid var(--border);
}
.cart-header h3 { font-weight: 400; font-size: 16px; letter-spacing: 0.5px; }

.cart-items { flex: 1; overflow-y: auto; padding: 14px 22px; }
.cart-empty { color: var(--text-muted); font-size: 14px; text-align: center; margin-top: 40px; }

.cart-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}
.cart-item-media {
  width: 54px;
  height: 54px;
  border-radius: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  flex-shrink: 0;
  overflow: hidden;
  background: var(--bg-alt);
}
.cart-item-media .bottle-icon { width: 26px; }
.cart-item-info { flex: 1; display: flex; flex-direction: column; gap: 4px; }
.cart-item-info strong { font-size: 13.5px; font-weight: 400; }
.cart-item-info span { font-size: 12px; color: var(--text-muted); }

.qty-control { display: flex; align-items: center; gap: 10px; margin-top: 4px; }
.qty-control button {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
}
.qty-control button:hover { border-color: var(--text); }
.qty-control span { font-size: 13px; min-width: 14px; text-align: center; }

.remove-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 6px;
}
.remove-btn:hover { color: var(--text); }

.wishlist-item-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.wishlist-item-actions .remove-btn.add-to-cart-btn:hover { color: var(--ink); }

.cart-item[data-wishlist-view], .cart-item[data-cart-view] { cursor: pointer; }
.cart-item[data-wishlist-view]:hover .cart-item-info strong, .cart-item[data-cart-view]:hover .cart-item-info strong { color: var(--ink); }

/* ---------- Product detail modal ---------- */
.pd-overlay {
  position: fixed;
  inset: 0;
  background: rgba(38, 26, 15, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 90;
  padding: 24px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s;
}
.pd-overlay.open { opacity: 1; pointer-events: auto; }
.pd-modal {
  position: relative;
  background: var(--surface);
  border-radius: 14px;
  max-width: 640px;
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.pd-close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
  background: rgba(251, 243, 228, 0.85);
  border: none;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  font-size: 18px;
  line-height: 1;
  color: var(--text);
  cursor: pointer;
}
.pd-close:hover { background: var(--on-hero); }
.pd-media { background: var(--bg-alt); display: flex; align-items: center; justify-content: center; padding: 30px; min-height: 280px; }
.pd-media img { width: 100%; height: 100%; max-height: 380px; object-fit: contain; }
.pd-media .bottle-icon { width: 90px; height: auto; color: rgba(255, 255, 255, 0.7); }
.pd-info { padding: 40px 34px; display: flex; flex-direction: column; gap: 14px; }
.pd-category { font-size: 11px; text-transform: uppercase; letter-spacing: 1.6px; color: var(--text-muted); }
.pd-name { font-family: var(--font-head); font-size: 25px; font-weight: 400; }
.pd-notes { color: var(--text-muted); font-size: 14px; line-height: 1.75; }
.pd-price { font-size: 18px; color: var(--text); margin-top: 4px; }

@media (max-width: 640px) {
  .pd-modal { grid-template-columns: 1fr; }
  .pd-media { min-height: 220px; }
}

.cart-footer { padding: 14px 22px 18px; border-top: 1px solid var(--border); flex-shrink: 0; }
.cart-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 6px;
}
.cart-total span { font-size: 12.5px; color: var(--text-muted); }
.cart-total strong { font-family: var(--font-head); font-weight: 400; font-size: 15.5px; color: var(--text); }
.cart-note { font-size: 10.5px; color: var(--text-muted); text-align: center; margin-top: 8px; }

.checkout-details { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 10px; }
/* The street line needs the full width; city and district share the row below. */
.checkout-input-wide { grid-column: 1 / -1; }
.checkout-input {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--text);
  background: var(--bg);
  width: 100%;
}
.checkout-input:focus { outline: none; border-color: var(--ink); }
.checkout-input.field-error { border-color: #8a3b2b; }

.coupon-toggle {
  display: block;
  background: none;
  border: none;
  padding: 0 0 10px;
  font-size: 11.5px;
  letter-spacing: 0.2px;
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  text-align: left;
}
.coupon-toggle:hover { color: var(--text); }

.coupon-field { display: flex; gap: 8px; margin-bottom: 4px; }
.coupon-field .checkout-input { text-transform: uppercase; }
.coupon-field .checkout-input::placeholder { text-transform: none; }
.coupon-field .btn-small { flex-shrink: 0; white-space: nowrap; }
.coupon-message { font-size: 11px; margin: 0 0 4px; min-height: 0; }
.coupon-message:empty { margin: 0; }
.coupon-message.error { color: #8a3b2b; margin-bottom: 8px; }
.coupon-message.success { color: #3d6b4c; margin-bottom: 8px; }

.coupon-discount-row strong { color: #3d6b4c; }
.coupon-remove { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 11px; padding: 0; }
.coupon-remove:hover { color: var(--text); }
.cart-total-final { border-top: 1px solid var(--border); padding-top: 12px; margin-top: 4px; }
.cart-total-final strong { font-family: var(--font-head); font-size: 17px; color: var(--text); }

/* ---------- Find Your Scent (quiz modal) ---------- */
.quiz-overlay {
  position: fixed;
  inset: 0;
  background: rgba(38, 26, 15, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 95;
  padding: 24px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s;
}
.quiz-overlay.open { opacity: 1; pointer-events: auto; }
.quiz-modal {
  position: relative;
  background: var(--surface);
  border-radius: 14px;
  max-width: 480px;
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
  padding: 46px 34px 38px;
  text-align: center;
}
.quiz-modal .pd-close { top: 14px; right: 14px; }

.quiz-progress { display: flex; justify-content: center; gap: 8px; margin-bottom: 30px; }
.quiz-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--border); transition: background 0.25s ease; }
.quiz-dot.active { background: var(--ink); }

.quiz-step { display: none; }
.quiz-step.active { display: block; }
.quiz-step h3 { font-family: var(--font-head); font-weight: 400; font-size: 21px; margin-bottom: 26px; }

.quiz-options { display: flex; flex-direction: column; gap: 10px; }
.quiz-option {
  padding: 15px 20px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
}
.quiz-option:hover { border-color: var(--ink); }
.quiz-option.selected { border-color: var(--ink); background: var(--bg-alt); }

.quiz-result-eyebrow { text-transform: uppercase; letter-spacing: 2.5px; font-size: 10.5px; color: var(--text-muted); margin-bottom: 18px; }
.quiz-result-media {
  width: 130px;
  height: 130px;
  margin: 0 auto 20px;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background-size: cover;
  background-position: center;
}
.quiz-result-media img { width: 100%; height: 100%; object-fit: cover; }
.quiz-result-media .bottle-icon { width: 40%; height: auto; color: var(--on-hero); }
.quiz-result-name { font-family: var(--font-head); font-weight: 400; font-size: 22px; margin-bottom: 6px; }
.quiz-result-family { font-size: 11px; text-transform: uppercase; letter-spacing: 1.6px; color: var(--text-muted); margin-bottom: 14px; }
.quiz-result-desc { color: var(--text-muted); font-size: 13.5px; line-height: 1.7; max-width: 360px; margin: 0 auto 16px; }
.quiz-result-price { font-family: var(--font-head); font-size: 20px; color: var(--ink); margin-bottom: 24px; }
.quiz-result-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-bottom: 18px; }
.quiz-restart { background: none; border: none; color: var(--text-muted); font-size: 12px; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.quiz-restart:hover { color: var(--text); }

@media (max-width: 640px) {
  .quiz-modal { padding: 40px 22px 30px; }
  .quiz-result-actions { flex-direction: column; }
  .quiz-result-actions .btn { width: 100%; }
}

/* ---------- Checkout modal (login-gated, bank transfer) ---------- */
.checkout-overlay {
  position: fixed;
  inset: 0;
  background: rgba(38, 26, 15, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 95;
  padding: 24px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s;
}
.checkout-overlay.open { opacity: 1; pointer-events: auto; }
.checkout-modal {
  position: relative;
  background: var(--surface);
  border-radius: 14px;
  max-width: 440px;
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
  padding: 40px 32px;
}
.checkout-modal .pd-close { top: 14px; right: 14px; }
.checkout-step { display: none; }
.checkout-step.active { display: block; }
.checkout-step h2 { font-weight: 400; font-size: 21px; margin-bottom: 8px; text-align: center; }
.checkout-step-sub { color: var(--text-muted); font-size: 13px; text-align: center; margin-bottom: 26px; }

/* min-height is sized to the taller (bank) variant so the box doesn't shrink
   and jolt the form when you switch to Express, which has only one row. */
.payment-details {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  margin-bottom: 20px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
  min-height: 130px;
}
.payment-details div { display: flex; justify-content: space-between; gap: 12px; font-size: 13.5px; }
.payment-details span { color: var(--text-muted); }
.payment-details strong { font-weight: 500; color: var(--text); text-align: right; }
/* Wraps a group of rows (bank vs. Express) so toggling one method doesn't
   need its own bordered box — it just disappears from the flex column.
   Needs !important since ".payment-details div" above (element+class) is
   otherwise more specific than the bare ".payment-method-rows" class. */
.payment-method-rows { display: contents !important; }
.payment-method-rows[hidden] { display: none !important; }

.payment-method-tabs { display: flex; gap: 10px; margin-bottom: 18px; }
.payment-method-tab {
  flex: 1;
  padding: 12px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: 12.5px;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.payment-method-tab:hover { border-color: var(--ink); }
.payment-method-tab.active { border-color: var(--ink); background: var(--bg-alt); color: var(--text); font-weight: 500; }

.receipt-upload {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 1px dashed var(--border);
  border-radius: 10px;
  padding: 16px;
  margin-bottom: 11px;
  font-size: 12.5px;
  color: var(--text-muted);
  cursor: pointer;
  text-align: center;
  transition: border-color 0.2s, color 0.2s;
}
.receipt-upload:hover { border-color: var(--ink); color: var(--text); }

.checkout-success-icon {
  width: 64px;
  height: 64px;
  margin: 0 auto 22px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--on-hero);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 30px;
  animation: checkout-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes checkout-pop {
  from { transform: scale(0); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

/* ---------- Page offset (pages without a full-bleed hero) ---------- */
.page-offset { padding-top: 84px; }

/* ---------- Inline alerts (auth forms, checkout) ----------
   Mirrors admin/css/admin.css's .admin-alert — reused by js/conta.js and
   js/checkout.js, neither of which loads the admin stylesheet. */
.admin-alert { padding: 12px 16px; border-radius: 8px; font-size: 13px; margin-bottom: 18px; }
.admin-alert-error { background: rgba(138, 59, 43, 0.1); color: #8a3b2b; }
.admin-alert-success { background: rgba(74, 124, 89, 0.12); color: #3d6b4c; }

/* ---------- Account (login / register / profile) ---------- */
.account-section { padding: 90px 0 110px; min-height: 68vh; }
.account-card { max-width: 460px; margin: 0 auto; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 44px 40px; }
.account-card h2 { font-weight: 400; font-size: 24px; text-align: center; margin-bottom: 30px; }

.account-tabs { display: flex; margin-bottom: 30px; border-bottom: 1px solid var(--border); }
.account-tab {
  flex: 1;
  text-align: center;
  padding: 12px;
  font-size: 11.5px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-muted);
  cursor: pointer;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  font-family: var(--font-body);
  margin-bottom: -1px;
  transition: color 0.2s, border-color 0.2s;
}
.account-tab.active { color: var(--text); border-bottom-color: var(--ink); }

.account-form-panel { display: none; }
.account-form-panel.active { display: block; }

.account-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.account-field label { font-size: 11px; letter-spacing: 0.6px; text-transform: uppercase; color: var(--text-muted); }
.account-field input, .account-field select {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--text);
  background: var(--bg);
  width: 100%;
}
.account-field input:focus, .account-field select:focus { outline: none; border-color: var(--ink); }
.phone-field { display: grid; grid-template-columns: 132px 1fr; gap: 10px; }

.account-note { text-align: center; font-size: 12px; color: var(--text-muted); margin-top: 4px; }
.account-note a { text-decoration: underline; color: var(--text); }

/* The profile fields are real inputs at all times, but until "Alterar dados"
   is pressed they're stripped of their box so they read as plain values —
   otherwise the account page looks permanently mid-edit. The ID selector
   outranks .account-field input, so no extra state class is needed. */
#profileView:not(.editing) .account-field input {
  border-color: transparent;
  background: transparent;
  padding-left: 0;
  pointer-events: none;
}
.account-edit-actions { display: none; flex-direction: column; gap: 10px; }
#profileView.editing .account-edit-actions { display: flex; }
#profileView.editing #editProfileBtn { display: none; }

.account-profile-row { display: flex; justify-content: space-between; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--border); font-size: 14px; }
.account-profile-row:last-of-type { border-bottom: none; }
.account-profile-row span:first-child { color: var(--text-muted); }
.account-profile-row span:last-child { text-align: right; }

/* ---------- Account: extended profile (stats / orders / favorites / referrals) ---------- */
.account-extra { max-width: 640px; margin: 30px auto 0; display: flex; flex-direction: column; gap: 20px; }
.account-block { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 30px 28px; }
.account-block h3 { font-family: var(--font-head); font-weight: 400; font-size: 18px; margin-bottom: 18px; }
.account-order-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border); font-size: 13.5px; }
.account-order-row:last-child { border-bottom: none; }
.account-order-row .order-status { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.6px; color: var(--text-muted); }

/* Each order lists what was actually in it, with the bottle alongside — a
   date and an item count don't tell you which perfume you bought. */
.account-order { border-bottom: 1px solid var(--border); padding-bottom: 14px; margin-bottom: 4px; }
.account-order:last-child { border-bottom: none; }
.account-order .account-order-row { border-bottom: none; padding-bottom: 4px; }
.account-order-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.account-order-item { display: flex; align-items: center; gap: 12px; }
.account-order-thumb {
  flex: 0 0 auto;
  width: 46px;
  height: 58px;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-alt);
  display: flex;
  align-items: center;
  justify-content: center;
}
.account-order-thumb img { width: 100%; height: 100%; object-fit: contain; }
.account-order-item-name { font-size: 13px; color: var(--text); display: flex; flex-direction: column; gap: 2px; }
.account-order-item-name small { font-size: 11.5px; color: var(--text-muted); }
.account-order-address { font-size: 11.5px; color: var(--text-muted); margin: 10px 0 0; }
.account-recs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.account-rec-card { display: block; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; text-align: center; padding: 14px 10px; transition: border-color 0.2s; }
@media (hover: hover) and (pointer: fine) {
  .account-rec-card:hover { border-color: var(--text); }
}
.account-rec-card img { width: 100%; height: 90px; object-fit: contain; margin-bottom: 8px; }
.account-rec-card strong { display: block; font-size: 12.5px; font-weight: 400; margin-bottom: 4px; }
.account-rec-card span { font-size: 11.5px; color: var(--text-muted); }
.referral-coupon-row { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; font-size: 13px; border-bottom: 1px solid var(--border); }
.referral-coupon-row:last-child { border-bottom: none; }

/* ---------- Responsive ---------- */
@media (max-width: 860px) {
  /* Cut down the desktop-sized vertical gaps between sections — they read
     as broken/empty space on a phone screen. */
  .featured { padding: 60px 0 50px; }
  .bestsellers { padding: 54px 0 44px; }
  .reviews { padding: 54px 0; }
  .newsletter { padding: 60px 0; }
  /* Single column, form first: the info cards are reference material, so on a
     phone they belong under the thing you actually came here to do. */
  .contato { padding: 54px 0 60px; }
  .contato-grid { grid-template-columns: 1fr; gap: 16px; }
  .contato-panel { padding: 28px 22px; border-radius: 12px; }
  .contato-panel h2 { font-size: 24px; }
  .contato-panel-sub { font-size: 13.5px; margin-bottom: 24px; }
  .contato-field-row { grid-template-columns: 1fr; gap: 0; }
  .contato-field { margin-bottom: 16px; }
  .contato-field input, .contato-field textarea { padding: 13px 15px; }
  .contato-field textarea { min-height: 120px; }
  .contato-aside { gap: 12px; }
  .contato-info { padding: 18px; border-radius: 12px; }
  .contato-info-icon { width: 40px; height: 40px; }
  .contato-info-value { font-size: 14px; }
  .processo { padding: 60px 0; }
  .colecao-banner { padding: 70px 0 48px; margin-bottom: 36px; }
  .sobre-banner-body { padding: 44px 0 60px; }
  .section-head { margin-bottom: 30px; }

  .main-nav {
    position: absolute;
    top: calc(100% + 10px);
    left: 16px;
    right: 16px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 14px 34px rgba(38, 26, 15, 0.16);
    flex-direction: column;
    padding: 10px;
    gap: 2px;
    display: none;
  }
  .main-nav.open { display: flex; }
  /* Text-transform/font-size aren't reset by the base ".main-nav a" rule
     above (it only sets color/spacing for the desktop horizontal layout),
     so without overriding them here the dropdown rendered as tiny 11.5px
     uppercase, low-contrast text — easy to mistake for an empty bar. The
     !important matches the color specificity fix below: .site-header.scrolled
     .main-nav a has higher specificity and would otherwise win and mute it. */
  .main-nav a, .main-nav button.mobile-nav-action {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    background: none;
    border: none;
    text-align: left;
    font-family: var(--font-body);
    text-transform: none !important;
    color: var(--text) !important;
    font-size: 14.5px !important;
    padding: 13px 14px;
    border-radius: 9px;
    letter-spacing: 0.3px;
    cursor: pointer;
  }
  .main-nav a svg, .main-nav button.mobile-nav-action svg { flex-shrink: 0; color: var(--ink); }
  .main-nav a:hover, .main-nav button.mobile-nav-action:hover { background: var(--bg-alt); }
  .main-nav-divider { display: block; height: 1px; background: var(--border); margin: 6px 4px; }
  .menu-btn { display: flex; }
  .header-actions { gap: 0; }
  .icon-btn { width: 36px; height: 36px; }
  .logo { font-size: 17px; }

  /* The "..." overflow menu only exists to keep search/account off the
     header row on desktop; on mobile those two are folded straight into
     the hamburger dropdown instead (see .mobile-nav-action above), so a
     shopper has exactly one menu control, not two adjacent ones. */
  .more-menu { display: none; }

  .hero { min-height: 68vh; align-items: flex-end; }
  .hero-inner { padding-top: 70px; padding-bottom: 56px; }
  .hero-media {
    background: url("../img/hero-mobile-bg.png") 84% center / cover no-repeat;
  }
  .hero-media::after {
    background: linear-gradient(180deg, rgba(38, 26, 15, 0.2) 0%, rgba(38, 26, 15, 0.3) 45%, rgba(38, 26, 15, 0.7) 100%);
  }

  /* Two up rather than one card per row. At full width these cards dwarfed
     everything else on the page and only one was ever visible at a time. */
  .featured-grid { grid-template-columns: repeat(2, 1fr); gap: 14px; }
  .featured-card .perfume-card-name { font-size: 14.5px; }
  .featured-card .perfume-card-price { font-size: 13px; }
  .featured-card .flip-back-name { font-size: 15px; }

  /* A dense grid so several perfumes are visible at once, instead of one
     giant card filling the whole screen per scroll. */
  .product-grid { grid-template-columns: repeat(2, 1fr); gap: 14px; }
  .wishlist-btn { width: 28px; height: 28px; top: 8px; right: 8px; }
  .wishlist-btn svg { width: 13px; height: 13px; }
  .perfume-badge { font-size: 8.5px; padding: 5px 8px; top: 8px; left: 8px; }
  .perfume-badge ~ .stock-badge { top: 38px; }
  .perfume-card-name { font-size: 14.5px; }
  .perfume-card-family { font-size: 9px; margin-bottom: 5px; }
  .perfume-card-desc { font-size: 11px; margin-bottom: 10px; }
  .perfume-card-price { font-size: 13px; }
  .perfume-card-footer .btn-small { padding: 8px 14px; font-size: 9.5px; }

  /* Caption plate, scaled for a two-up grid. */
  .flip-front { border-radius: 16px; padding: 7px 7px 0; }
  .flip-front .perfume-card-body { margin: 7px -7px 0; padding: 10px 9px 12px; gap: 4px; border-radius: 0 0 15px 15px; }
  .flip-front .perfume-card-name { font-size: 13.5px; min-height: 2.2em; }
  .flip-front .perfume-card-price { font-size: 12.5px; }
  .flip-front .price-original { font-size: 10px; }
  .flip-front .price-badge { font-size: 8px; padding: 1px 5px; }

  /* Slightly smaller bottles with rounder corners: a shorter panel than the
     3/4 default leaves the card less dominant in a two-up grid. */
  .perfume-card-media-wrap { aspect-ratio: 4 / 5; border-radius: 10px; }
  /* Fills the panel rather than fitting inside it. "contain" scaled the bottle
     down until it fitted, which left bands of empty surface above and below it
     on any photo whose shape didn't match the 4/5 panel. */
  .perfume-card-media { background-size: cover; background-position: center; }
  .flip-back { border-radius: 16px; padding: 17px 15px; }
  .flip-back-name { font-size: 15px; }
  .flip-back-brand { font-size: 8.5px; }
  .flip-note-label { flex-basis: 40px; font-size: 8px; }
  .flip-note-value { font-size: 10.5px; }
  .flip-back-fallback { font-size: 10.5px; -webkit-line-clamp: 4; }
  .flip-back-notes { padding: 9px 0; margin: 8px 0; gap: 5px; }
  .flip-back-size { font-size: 9px; }
  .flip-back-price, .flip-back-price .price-final { font-size: 13px; }
  .flip-back-meta { margin-bottom: 9px; }

  /* Full-bleed photo with the story text overlaid on top, instead of a
     stacked image-then-gap-then-text layout with dead white space between. */
  .historia { padding: 0; }
  .historia-inner { position: relative; display: block; min-height: 82vh; gap: 0; }
  .historia-media { position: absolute; inset: 0; }
  .historia-media img { height: 100%; }
  .historia-media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(38, 26, 15, 0.08) 0%, rgba(38, 26, 15, 0.18) 45%, rgba(38, 26, 15, 0.84) 100%);
  }
  .historia-content {
    position: relative;
    z-index: 1;
    min-height: 82vh;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 0 24px 50px;
  }
  .historia-content .eyebrow, .historia-content h2 { color: var(--on-hero); }
  .historia-content p { color: rgba(251, 243, 228, 0.85); max-width: none; }
  .historia-content .btn-outline-gold { align-self: flex-start; }
  .sobre-stats { gap: 26px; flex-wrap: wrap; }

  .sobre-banner-media { height: 48vh; min-height: 340px; }
  .sobre-banner-overlay { padding-bottom: 36px; }
  .sobre-banner-body { padding: 40px 0 56px; }
  /* Roomier than it was: the story used to sit hard against the card border,
     which is what made this page feel claustrophobic on a phone. */
  .sobre-banner-text { padding: 34px 24px; }
  .sobre-banner-body .sobre-stats { padding: 24px 24px 0; gap: 12px; }
  .sobre-banner-text p { font-size: 14.5px; line-height: 2.05; margin-bottom: 26px; }
  .sobre-banner-overlay-inner { padding-top: 84px; padding-bottom: 40px; }
  .sobre-banner-mark { padding-left: 12px; }
  .sobre-banner-place { font-size: 9px; letter-spacing: 2px; }
  .sobre-banner-line { font-size: 13.5px; margin-top: 5px; }
  .processo-inner { grid-template-columns: 1fr; gap: 30px; }
  .processo-media::before { display: none; }
  .processo-media img { height: 320px; }
  .processo-quote, .processo-content h2, .processo-content p { max-width: none; }

  /* "Experiências reais" becomes a swipeable, centre-snapped strip on mobile
     instead of a cramped 1-col grid — see js/main.js for the auto-advance
     that walks it round on a loop. */

  /* Center-snap carousel: the active card sits in the middle with the next
     one peeking on each side, instead of stacking flush against the left edge. */
  /* Was calc(50% - 118px) to centre the first card, which left a wide empty
     strip between the edge of the screen and the first perfume. Snapping to
     the start instead puts the first bottle right where the section begins. */
  .carousel { scroll-padding-left: 16px; }
  .carousel-track { gap: 16px; padding: 24px 16px 10px; }
  .carousel-card, .carousel-end-card { width: 232px; min-height: 400px; scroll-snap-align: start; }
  .carousel-controls { justify-content: center; }

  /* Continuous marquee. The viewport just clips; all motion is one transform
     on .reviews-track, so every card moves identically — see js/main.js.
     There is no scrolling container and no scroll-snap here on purpose: both
     were what made cards move at different rates in earlier versions. */
  .reviews-grid {
    overflow: hidden;
    background: none;
    padding: 4px 0 6px;
    /* pan-y leaves vertical swipes to the page while this strip takes the
       horizontal ones, so dragging a comment never blocks page scrolling. */
    touch-action: pan-y;
    cursor: grab;
  }
  .reviews-grid.is-dragging { cursor: grabbing; }
  .reviews-track {
    display: flex;
    flex-wrap: nowrap;
    width: max-content;
    gap: 0;
    background: none;
    /* The drift lives in js/main.js, not in a CSS animation: a finger and the
       clock have to write to the same position, and an animation gives the
       finger nothing to move. */
    will-change: transform;
  }
  /* margin-right rather than a flex gap: the track is exactly two identical
     halves only if every card occupies the same width INCLUDING its spacing.
     With `gap`, N cards have N-1 gaps and -50% would drift a little each loop. */
  .review-card { flex: 0 0 82vw; margin-right: 14px; border-radius: 12px; }
  .review-card[data-clone] { display: block; }

  /* The keyframes are gone: the drift is driven frame by frame in js/main.js
     so a drag can write to the same position. Reduced motion is honoured
     there too — the drift stops, dragging still works. */

  .newsletter-form { flex-direction: column; }
  .newsletter-inner { padding: 44px 26px; }

  /* Brand across the top, then Loja and Ajuda side by side, then the contact
     block full width — one column each would make the footer endless. */
  .site-footer { padding: 44px 0 22px; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 28px 24px; padding-bottom: 30px; }
  .footer-brand { grid-column: 1 / -1; }
  .footer-contact { grid-column: 1 / -1; }
  .footer-col { font-size: 12.5px; gap: 10px; }

  .footer-bottom { flex-direction: column; text-align: center; }

  .account-card { padding: 32px 22px; }
  .phone-field { grid-template-columns: 108px 1fr; }

  .checkout-modal { padding: 30px 22px; }
  .checkout-details { grid-template-columns: 1fr; }
}

/* ---------- Legal pages ---------- */
.legal-updated { font-size: 12.5px; color: var(--text-muted); letter-spacing: 0.3px; }
.policy-block h3 { text-align: left; }
.policy-block ul { margin: 0 0 14px; padding-left: 20px; color: var(--text-muted); font-size: 15px; line-height: 1.9; }
.policy-block li { margin-bottom: 6px; }
.policy-block a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }

/* Footer: copyright on one line, the legal links on their own. */
.footer-legal { display: flex; align-items: center; gap: 8px; }
.footer-legal a { text-decoration: underline; text-underline-offset: 2px; }
.footer-legal span { opacity: 0.45; }

/* A social account that does not exist yet: the icon is shown so the row is
   complete, but it is not a link, because a link that goes nowhere is worse
   than no link. */
.social-soon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px dashed rgba(251, 243, 228, 0.28);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.45;
  cursor: default;
}

@media (max-width: 640px) {
  .policy-block ul { font-size: 14.5px; }
  .footer-legal { justify-content: center; }
}

/* Acceptance of the Terms and the Privacy Policy, taken where a commitment is
   made. The control keeps its own size and sits against the first line. */
.legal-accept {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 4px 0 16px;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-muted);
  cursor: pointer;
}
.legal-accept input[type="checkbox"] {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin: 2px 0 0;
  accent-color: var(--ink);
  cursor: pointer;
}
.legal-accept a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.newsletter-legal { margin: 12px 0 0; font-size: 11.5px; color: var(--text-muted); }
.newsletter-legal a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* A quiet text link inside a form — "Esqueceu-se da palavra-passe?" and the
   way back from the recovery panel. */
.link-quiet {
  display: block;
  width: 100%;
  margin-top: 14px;
  padding: 0;
  background: none;
  border: none;
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--text-muted);
  text-align: center;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.link-quiet:hover { color: var(--text); }
.panel-lead { font-size: 13.5px; line-height: 1.7; color: var(--text-muted); margin: 0 0 20px; }
.field-hint { font-size: 11.5px; color: var(--text-muted); margin: 5px 0 0; }
.account-card-narrow { max-width: 460px; margin-left: auto; margin-right: auto; }
.account-title { font-family: var(--font-head); font-weight: 400; font-size: 24px; margin: 0 0 10px; }

/* Marks a favourite that is already in the basket. The item stays in the list
   either way — favourites are saved deliberately, not consumed by buying. */
.in-cart-tag {
  display: inline-block;
  margin-top: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--bg-alt);
  color: var(--ink);
  font-size: 9.5px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
}

/* Promotional banner: a strip inside the header, so it travels with it and
   needs no layout offset of its own on the fixed-header home page. */


/* ---------- B3: zonas de entrega ---------- */
/* The zone selector sits with the address fields, and the running total sits
   directly under it, so the delivery cost is read before the payment step. */
.checkout-zone { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.checkout-zone label {
  font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-muted); font-weight: 600;
}
/* The native select is kept deliberately: on a phone it opens the platform
   picker, which is far easier to use than anything custom, and it keeps its
   own dropdown arrow. Only the height is normalised, since a bare select
   renders shorter than the text inputs beside it. */
.checkout-zone select.checkout-input { width: 100%; min-height: 44px; }
.zone-note {
  margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--text-muted);
  background: var(--bg-soft); border-left: 2px solid var(--ink);
  padding: 9px 11px; border-radius: 0 6px 6px 0;
}

.checkout-totals { margin: 4px 0 18px; display: flex; flex-direction: column; gap: 7px; }
.checkout-totals:empty { display: none; }
.ck-total-row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  font-size: 13.5px; color: var(--text-muted);
}
/* The value never breaks; the label wraps instead. min-width:0 is what lets it
   wrap at all — without it a long zone name ("Luanda Centro / Ingombota") would
   push the price off the edge of a narrow phone. */
.ck-total-row span:first-child { min-width: 0; overflow-wrap: anywhere; }
.ck-total-row span:last-child { white-space: nowrap; flex-shrink: 0; }
.ck-total-final {
  border-top: 1px solid var(--border); padding-top: 10px; margin-top: 3px;
  font-family: var(--font-head); font-size: 16px; color: var(--text);
}

.cart-delivery-hint {
  margin: 0 0 10px; font-size: 12px; line-height: 1.45; color: var(--text-muted);
  text-align: right;
}

/* The zone table in Políticas has to stay readable on a phone, where a normal
   table would force the page to scroll sideways. */
.zone-table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.zone-table { width: 100%; border-collapse: collapse; margin: 14px 0 6px; font-size: 14px; }
.zone-table td:first-child { overflow-wrap: anywhere; }
.zone-table th, .zone-table td {
  text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border);
}
.zone-table th {
  font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-muted); font-weight: 600;
}
.zone-table td:last-child, .zone-table th:last-child { text-align: right; white-space: nowrap; }

@media (max-width: 640px) {
  .zone-table { font-size: 13px; }
  .zone-table th, .zone-table td { padding: 9px 6px; }
  .ck-total-row { font-size: 13px; }
  .ck-total-final { font-size: 15px; }
}

.zone-table-title {
  font-family: var(--font-head); font-size: 17px; color: var(--text);
  margin: 22px 0 0; font-weight: 500;
}
.policy-note { font-size: 13.5px; color: var(--text-muted); line-height: 1.6; margin: 10px 0 0; }

/* The notes area is the flexible middle of the back face, so it can shrink;
   min-height:0 lets it, and overflow:hidden means a wordy product clips its own
   text instead of pushing the add-to-cart button off the bottom of the card. */
.flip-back-notes { min-height: 0; overflow: hidden; }

/* The size next to a cart line's name, so the same perfume twice reads as two
   different bottles rather than a duplicated row. */
.cart-item-size {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 9.5px;
  font-weight: 400;
  letter-spacing: .06em;
  color: var(--text-muted);
  vertical-align: middle;
}

@media (max-width: 640px) {
pill mobile rules  .cart-item-size { font-size: 9px; margin-left: 5px; }
}

/* ---------- Frasco completo / amostra ----------
   Two rows rather than pills: each option carries a price, and a price needs
   room to be read. The mark on the left is a radio in everything but name —
   these are mutually exclusive choices, and they should look it. */
.option-picker { display: flex; flex-direction: column; gap: 6px; margin: 0 0 10px; }
.option-row {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 7px 10px;
  border: 1px solid var(--border); border-radius: 10px;
  background: transparent;
  font-family: var(--font-body); font-size: 12px; color: var(--text);
  text-align: left; cursor: pointer;
  transition: border-color .18s, background .18s;
  -webkit-tap-highlight-color: transparent;
}
.option-mark {
  flex: 0 0 auto; width: 13px; height: 13px; border-radius: 50%;
  border: 1px solid var(--text-muted); position: relative;
}
.option-row.selected { border-color: var(--ink); background: var(--bg-soft); }
.option-row.selected .option-mark { border-color: var(--ink); }
.option-row.selected .option-mark::after {
  content: ""; position: absolute; inset: 2.5px; border-radius: 50%; background: var(--ink);
}
.option-label { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.option-price { flex: 0 0 auto; font-weight: 500; white-space: nowrap; }
/* Still listed, never selectable: hiding it would make the range look smaller
   than it is, and silently switching sells someone the wrong thing. */
.option-row.out { opacity: .45; cursor: not-allowed; }
.option-row.out .option-price { font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
@media (hover: hover) and (pointer: fine) {
  .option-row:not(.out):not(.selected):hover { border-color: var(--ink); }
}

/* The reason to buy an amostra at all. Discreet, but it has to be readable —
   nobody buys a thing whose point they have to work out. */
.amostra-note {
  border-left: 2px solid var(--ink);
  background: var(--bg-soft);
  padding: 9px 11px; border-radius: 0 8px 8px 0;
  margin: 0 0 10px;
}
.amostra-note strong {
  display: block; font-family: var(--font-head); font-weight: 500;
  font-size: 12.5px; color: var(--text); margin-bottom: 3px;
}
.amostra-note p { margin: 0; font-size: 11px; line-height: 1.5; color: var(--text-muted); }

/* The modal has room to breathe. */
.pd-sizes .option-row { font-size: 13.5px; padding: 11px 13px; }
.pd-sizes .amostra-note { padding: 12px 14px; }
.pd-sizes .amostra-note strong { font-size: 14px; }
.pd-sizes .amostra-note p { font-size: 12.5px; }
.pd-sizes:empty { display: none; }

@media (max-width: 640px) {
  .option-picker { gap: 5px; margin-bottom: 8px; }
  .option-row { font-size: 11px; padding: 8px 9px; gap: 7px; }
  .option-mark { width: 12px; height: 12px; }
  .amostra-note { padding: 8px 10px; }
  .amostra-note strong { font-size: 11.5px; }
  .amostra-note p { font-size: 10.5px; }
  .pd-sizes .option-row { font-size: 13px; padding: 10px 12px; }
}

/* ---------- Campaign on the storefront ---------- */
/* Under the price, where the saving is. Deliberately quiet: it is a reassurance
   about how long the price lasts, not a second piece of shouting. */
.campaign-until {
  display: block;
  font-size: 10px;
  letter-spacing: .9px;
  text-transform: uppercase;
  color: var(--ink);
  margin-top: 4px;
}
.pd-price .campaign-until { font-size: 11px; margin-top: 6px; }


/* Arriving from the banner shows part of the collection, so the page says which
   part, and offers the way back out. */
.campaign-banner-note {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin: 0 0 22px;
  padding: 12px 16px;
  border-left: 2px solid var(--ink);
  background: var(--bg-soft);
  border-radius: 0 8px 8px 0;
}
.campaign-banner-note strong {
  font-family: var(--font-head); font-weight: 500; font-size: 16px; color: var(--text);
}
.campaign-banner-note span { font-size: 13px; color: var(--text-muted); }
.campaign-banner-note a {
  margin-left: auto; font-size: 12.5px; color: var(--ink);
  text-decoration: underline; text-underline-offset: 3px;
}

@media (max-width: 640px) {
  .campaign-until { font-size: 9px; letter-spacing: .7px; }
  .campaign-banner-note { padding: 10px 12px; margin-bottom: 16px; }
  .campaign-banner-note strong { font-size: 14.5px; }
  .campaign-banner-note a { margin-left: 0; }
}

/* The back of a card has a fixed height it cannot exceed, and the scent notes
   were the part being squeezed out of it. The buying controls are compact on a
   card (the detail modal keeps the roomier version), which gives the notes the
   space they were short of. Measured: they no longer clip at 390px or 1280px. */
.flip-back .option-picker { gap: 5px; margin-bottom: 8px; }
.flip-back .option-row { padding: 6px 9px; font-size: 11px; gap: 7px; }
.flip-back .option-mark { width: 11px; height: 11px; }
.flip-back .flip-back-actions .btn-small { padding-top: 9px; padding-bottom: 9px; }

/* One floor for all three card types. Their height otherwise comes entirely
   from the photo aspect ratio, which left the back face shorter than its own
   contents; and only the collection grid had been given a floor, so the same
   perfume looked like two different designs on two pages. The front absorbs the
   extra in its caption plate, whose name and price are already centred. */
.product-card, .featured-card { min-height: 452px; }
@media (max-width: 900px) {
  .product-card, .featured-card { min-height: 428px; }
}
@media (max-width: 640px) {
  .product-card, .featured-card { min-height: 400px; }
}

/* ---------- Legal pages: index beside the document ---------- */
/* One reading column, centred. No index: these are documents to be read
   through, and a list of shortcuts invites skipping. */
.legal-layout { max-width: 720px; margin: 0 auto; }
.legal-doc { min-width: 0; }


/* Sections arrive as they are reached. Applied by script, never by the
   stylesheet alone: if the script fails the document must still be readable. */
.policy-block.legal-hidden { opacity: 0; transform: translateY(14px); }
.policy-block {
  transition: opacity 0.6s cubic-bezier(0.2, 0.6, 0.2, 1),
              transform 0.6s cubic-bezier(0.2, 0.6, 0.2, 1);
}

@media (max-width: 900px) {
  .legal-layout { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .policy-block { padding-bottom: 30px; }
  .policy-block + .policy-block { padding-top: 30px; }
  .policy-block h3 { font-size: 19px; }
}
@media (prefers-reduced-motion: reduce) {
  .policy-block { transition: none; }
}

/* ---------- Motion, everywhere rather than on the home page only ----------
   The collection, contact and policy pages had no reveal at all, which is what
   made them feel flat next to the home page. They use the same system now; what
   follows is the finer movement that was missing throughout. */

/* Photographs settle rather than snap. Applies to every card image, the story
   photo and the about-page banner alike. */
.perfume-card-media,
.historia-media img,
.sobre-banner-media img,
.processo-media img {
  transition: transform 0.7s cubic-bezier(0.2, 0.6, 0.2, 1);
}
@media (hover: hover) and (pointer: fine) {
  .historia-media:hover img,
  .processo-media:hover img { transform: scale(1.03); }
}

/* A photo that has just decoded fades up instead of appearing mid-scroll. */
.perfume-card-media-wrap:not(.is-loading) .perfume-card-media {
  animation: media-in 0.55s cubic-bezier(0.2, 0.6, 0.2, 1) both;
}
@keyframes media-in { from { opacity: 0; } to { opacity: 1; } }

/* Anything that reacts to a press gets the same easing, so the site moves in
   one language rather than each control having its own. */
.btn, .btn-small, .icon-btn, .filter-btn, .more-menu-item,
.faq-item summary, .footer-col a, .main-nav a {
  transition: color 0.25s ease, background-color 0.25s ease,
              border-color 0.25s ease, opacity 0.25s ease, transform 0.25s ease;
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover, .btn-small:hover { transform: translateY(-1px); }
  .footer-col a:hover { opacity: 1; }
}

/* The accordion opens instead of jumping. */
.faq-item summary { cursor: pointer; }
.faq-item[open] summary ~ * { animation: faq-open 0.35s cubic-bezier(0.2, 0.6, 0.2, 1) both; }
@keyframes faq-open {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Every one of these is a preference, not a decoration: honoured when the
   reader has asked the system for less movement. */
@media (prefers-reduced-motion: reduce) {
  .perfume-card-media,
  .historia-media img,
  .sobre-banner-media img,
  .processo-media img,
  .btn, .btn-small, .icon-btn, .filter-btn, .more-menu-item,
  .faq-item summary, .footer-col a, .main-nav a { transition: none; }
  .perfume-card-media-wrap:not(.is-loading) .perfume-card-media,
  .faq-item[open] summary ~ * { animation: none; }
}


/* ---------- The one bar at the top of the site ----------
   Exactly one slot, never two. It sits BEFORE the header in the document, not
   inside it: the header is fixed, so a bar inside it was fixed too and could
   never scroll away. From out here it scrolls with the page while js/main.js
   walks the header down to meet it and then pins it at the top.

   --topbar-h is set by script to the bar's measured height and is 0 when there
   is no bar, which is what leaves no empty strip behind when it is switched
   off or dismissed. */
:root { --topbar-h: 0px; }

.site-topbar {
  position: relative;
  z-index: 61;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px 14px;
  flex-wrap: wrap;
  padding: 10px 44px;
  background: var(--ink);
  color: var(--on-hero);
  text-align: center;
}
.site-topbar-text {
  font-size: 12px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  line-height: 1.4;
}
.site-topbar-cta {
  color: inherit;
  font-size: 12px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
  transition: opacity 0.25s ease;
}
/* Absolute so the message stays centred on the bar rather than being shoved
   off-centre by the close button's width. */
.site-topbar-close {
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.25s ease, background-color 0.25s ease;
  -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) and (pointer: fine) {
  .site-topbar-cta:hover { opacity: 0.75; }
  .site-topbar-close:hover { opacity: 1; background: rgba(255, 255, 255, 0.12); }
}

/* Pages whose content clears the fixed header have to clear the bar as well,
   or the first heading hides underneath it. */
body.has-topbar .page-offset { padding-top: calc(84px + var(--topbar-h)); }

@media (max-width: 640px) {
  .site-topbar { padding: 9px 40px; gap: 4px 10px; }
  .site-topbar-text, .site-topbar-cta { font-size: 10.5px; letter-spacing: 1px; }
  .site-topbar-close { right: 6px; width: 26px; height: 26px; font-size: 18px; }
}
