/* ══════════════════════════════════════════════════════════════════
   HAVANA SMOKE SHOP AND CIGAR - single-page storefront mockup
   GT Studios base layer, forked. Identity: Karla display + Bitter
   held back for the cigar moment, ember accent on a graphite ground.

   The page is light-first: bone and white carry the hero, the category
   mosaic and the shop. Dark is used three times on purpose - the cigar
   strip, the visit block and the footer - so contrast stays a decision
   rather than a default.
   ══════════════════════════════════════════════════════════════════ */

:root{
  /* ── grounds - cool graphite, so the shop reads current rather
        than like a panelled cigar room ──────────────────────── */
  --ground:   #16191C;   /* graphite */
  --ground-2: #1E2328;   /* raised dark surface */
  --ground-3: #282E34;   /* dark hover */
  --ember:    #2B1E19;   /* warm dark. The cigar tile, and nothing else */
  --bg:       #F7F6F4;   /* near-white page ground */
  --panel:    #FFFFFF;
  --sand:     #EBE9E5;   /* light warm grey, alt band */

  /* ── ink ─────────────────────────────────────────────────── */
  --ink:       #17191C;
  --ink-2:     #4C5257;
  --muted:     #6E757B;
  --on-dark:   #EEF0F2;
  --on-dark-2: #B7BEC4;
  --on-dark-3: #8D959C;

  --line:      rgba(23,25,28,.14);
  --line-dark: rgba(238,240,242,.15);

  /* ── identity - the three per-client variables ────────────── */
  --accent:      #F2703F;   /* ember orange, on dark grounds. 5.9:1 */
  --accent-deep: #C43F16;   /* ember orange, AA-safe on bone and white */
  --warm:        #C9954E;   /* amber. Cigar strip only */

  --font-display: "Bitter", "Bookman Old Style", Georgia, "Times New Roman", serif;
  --font-body:    "Karla", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* ── structure ───────────────────────────────────────────── */
  --wrap: 1240px;  --wide: 1440px;
  --gutter: clamp(20px, 5vw, 72px);
  --section-y: clamp(64px, 10vw, 132px);
  --nav-h: 76px;
  --callbar-h: 0px;

  --radius: 14px;  --radius-lg: 20px;  --pill: 999px;

  --shadow-sm: 0 1px 3px rgba(23,25,28,.09);
  --shadow-md: 0 18px 44px -22px rgba(23,25,28,.36);
  --shadow-lg: 0 34px 80px -30px rgba(15,18,21,.5);

  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* ── reset ─────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth}
section[id],#top{scroll-margin-top:calc(var(--nav-h) + 12px)}
body{
  margin:0; background:var(--ground); color:var(--ink);
  font-family:var(--font-body);
  font-size:clamp(1rem,.97rem + .18vw,1.075rem);
  line-height:1.7; font-weight:400;
  overflow-x:clip; -webkit-font-smoothing:antialiased;
}
img,svg,video{display:block; max-width:100%}
img{height:auto}
a{color:inherit}
button{font:inherit; color:inherit; background:none; border:0; cursor:pointer}
/* Headings run on Karla, not Bitter. The serif was doing most of the work
   that made the old page read as a cigar lounge; it is now held back for
   the wordmark, the age gate and the cigar strip, where it earns its place. */
h1,h2,h3{margin:0; font-family:var(--font-body); font-weight:700; line-height:1.06; letter-spacing:-.022em}
.serif{font-family:var(--font-display); font-weight:500; letter-spacing:-.008em; line-height:1.06}
p{margin:0}
ul{margin:0; padding:0; list-style:none}

/* Body scroll is locked until the age gate is answered. This works with
   JavaScript disabled too, since .verified is only ever added by script. */
html:not(.verified) body{overflow:hidden}

/* ── type scale ────────────────────────────────────────────── */
.h-hero{font-size:clamp(2.55rem,1.5rem + 4.6vw,5.3rem); line-height:.96; letter-spacing:-.032em}
.h-1{font-size:clamp(1.95rem,1.4rem + 2.3vw,3.25rem); letter-spacing:-.028em}
.h-2{font-size:clamp(1.4rem,1.15rem + 1.1vw,2.05rem); letter-spacing:-.024em}
.h-3{font-size:clamp(1.12rem,1.03rem + .4vw,1.4rem); line-height:1.2}

.eyebrow{
  font-family:var(--font-body); font-size:.7rem; font-weight:600;
  letter-spacing:.2em; text-transform:uppercase; line-height:1;
  color:var(--accent-deep); display:flex; align-items:center; gap:.85em;
}
.eyebrow::after{content:""; flex:0 0 44px; height:1px; background:currentColor; opacity:.45}
.eyebrow.is-plain::after{display:none}
.band-dark .eyebrow,.tile-dark .eyebrow,.tile-raised .eyebrow,.tile-ember .eyebrow{color:var(--accent)}

.lead{font-size:clamp(1.05rem,1rem + .3vw,1.22rem); line-height:1.62; color:var(--ink-2)}
.band-dark .lead{color:var(--on-dark-2)}
.fine{font-size:.82rem; line-height:1.6; color:var(--muted)}
.band-dark .fine{color:var(--on-dark-3)}

/* ── layout ────────────────────────────────────────────────── */
.wrap{width:min(100% - var(--gutter)*2, var(--wrap)); margin-inline:auto}
.wide{width:min(100% - var(--gutter)*2, var(--wide)); margin-inline:auto}
.band{padding-block:var(--section-y)}
.band-bone{background:var(--bg); color:var(--ink)}
.band-sand{background:var(--sand); color:var(--ink)}
.band-dark{background:var(--ground); color:var(--on-dark)}
.band-flush{padding-block:0}
.band-head{max-width:44rem; margin-bottom:clamp(30px,4vw,54px)}
.band-head .eyebrow{margin-bottom:clamp(16px,2.2vw,24px)}
.band-head h2{margin-bottom:16px}
.is-centered{text-align:center; margin-inline:auto}
.is-centered .eyebrow{justify-content:center}
.is-centered .eyebrow::before{content:""; flex:0 0 44px; height:1px; background:currentColor; opacity:.45}
.is-centered .lead,.is-centered p{margin-inline:auto}

/* ── buttons ───────────────────────────────────────────────── */
.btn{
  display:inline-flex; align-items:center; gap:.62em;
  font-family:var(--font-body); font-weight:600; font-size:.92rem; letter-spacing:.01em;
  padding:.92em 1.6em; border-radius:var(--pill); text-decoration:none;
  transition:transform .4s var(--ease), background-color .4s var(--ease), border-color .4s var(--ease), color .4s var(--ease);
}
.btn .ar{transition:transform .4s var(--ease)}
.btn:hover{transform:translateY(-2px)}
.btn:hover .ar{transform:translateX(4px)}
.btn-fill{background:var(--accent-deep); color:#fff}
.btn-fill:hover{background:#A63311}
.btn-on-dark{background:var(--on-dark); color:var(--ground)}
.btn-on-dark:hover{background:#fff}
.btn-ghost{border:1px solid var(--line); color:var(--ink)}
.btn-ghost:hover{border-color:var(--ink); background:rgba(23,25,28,.04)}
.btn-ghost-dark{border:1px solid var(--line-dark); color:var(--on-dark)}
.btn-ghost-dark:hover{border-color:var(--on-dark); background:rgba(238,240,242,.06)}

.arrow-link{
  display:inline-flex; align-items:center; gap:.6em; text-decoration:none;
  font-weight:600; font-size:.9rem; padding-block:.4em;
  border-bottom:1px solid transparent; transition:border-color .4s var(--ease), color .4s var(--ease);
}
.arrow-link .ar{transition:transform .4s var(--ease)}
.arrow-link:hover .ar{transform:translateX(5px)}
.arrow-link:hover{border-bottom-color:currentColor}

/* Arrow glyph, drawn as an inline mask so it costs no request and no icon font. */
.ar{
  width:1.05em; height:1em; flex:0 0 auto; background:currentColor;
  -webkit-mask:var(--ar) center/contain no-repeat; mask:var(--ar) center/contain no-repeat;
}
:root{
  --ar:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cpath d='M0 6h21M16 1l5 5-5 5' fill='none' stroke='%23000' stroke-width='1.6'/%3E%3C/svg%3E");
  --star:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l2.9 6.6 7.1.6-5.4 4.7 1.6 7L12 17.3 5.8 20.9l1.6-7L2 9.2l7.1-.6z' fill='%23000'/%3E%3C/svg%3E");
}

/* ── focus ─────────────────────────────────────────────────── */
:focus-visible{outline:2px solid var(--accent); outline-offset:3px; border-radius:3px}
[tabindex="-1"]:focus,[tabindex="-1"]:focus-visible{outline:none}
.band-bone :focus-visible,.band-sand :focus-visible{outline-color:var(--accent-deep)}
.skip{
  position:fixed; top:10px; left:10px; z-index:120; transform:translateY(-200%);
  background:var(--accent-deep); color:#fff; padding:.7em 1.2em;
  border-radius:var(--pill); font-weight:600; font-size:.88rem; text-decoration:none;
  transition:transform .3s var(--ease);
}
.skip:focus-visible{transform:none}

/* ══ AGE GATE ═════════════════════════════════════════════════
   Rendered in markup so it stands with JavaScript disabled. The inline
   head script adds .verified before first paint, so a returning visitor
   in the same session never sees it flash. */
.gate{
  position:fixed; inset:0; z-index:200;
  display:grid; place-items:center; padding:var(--gutter);
  background:var(--panel); color:var(--ink); overflow-y:auto;
}
html.verified .gate{display:none}
/* The warm smoke plate that used to sit here belonged to the old
   direction. A quiet ember wash does the same job without it. */
.gate-veil{display:none}
.gate::before{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(ellipse 70% 60% at 50% 34%,rgba(196,63,22,.07) 0%,rgba(196,63,22,0) 70%);
}
.gate-panel{position:relative; width:min(100%,540px); text-align:center; padding-block:clamp(24px,6vw,48px)}
.gate-mark{width:56px; height:56px; margin:0 auto 30px; color:var(--accent-deep)}
.gate-name{
  font-family:var(--font-body); font-size:clamp(1.4rem,1.15rem + 1.1vw,1.95rem);
  letter-spacing:.09em; text-transform:uppercase; margin-bottom:6px; font-weight:700;
}
.gate-place{font-size:.68rem; font-weight:600; letter-spacing:.22em; text-transform:uppercase; color:var(--muted)}
.gate-rule{width:44px; height:2px; background:var(--accent-deep); margin:26px auto}
.gate-q{font-size:clamp(1.55rem,1.2rem + 1.7vw,2.4rem); margin-bottom:16px}
.gate-sub{color:var(--ink-2); font-size:1rem; margin-bottom:34px}
.gate-actions{display:flex; flex-wrap:wrap; gap:12px; justify-content:center; margin-bottom:30px}
.gate-actions .btn{min-width:196px; justify-content:center}
.gate-fine{color:var(--muted); font-size:.78rem; line-height:1.65; max-width:40ch; margin-inline:auto}
.gate noscript{display:block; margin-top:22px; color:var(--accent-deep); font-size:.85rem}
.gate-deny .gate-q{font-size:clamp(1.35rem,1.1rem + 1.2vw,1.9rem)}

/* ══ NAV ══════════════════════════════════════════════════════ */
.hdr{
  position:fixed; inset-block-start:0; inset-inline:0; z-index:90; height:var(--nav-h);
  display:flex; align-items:center;
  transition:transform .45s var(--ease);
  /* Solid from the first pixel of scroll, on every page. The old header was
     transparent over the hero and only took a background once stuck, which
     left it floating over a white column. */
  background:var(--ground); color:var(--on-dark);
  border-bottom:1px solid var(--line-dark);
}
/* Nothing changes on scroll now beyond the shadow: the bar is already
   opaque, so there is no state to fade into. */
.hdr.is-stuck{box-shadow:0 1px 0 rgba(0,0,0,.28)}
.hdr-in{display:flex; align-items:center; justify-content:space-between; gap:14px; width:min(100% - var(--gutter)*2,var(--wide)); margin-inline:auto}
.hdr-right{display:flex; align-items:center; gap:10px}
.brand{display:inline-flex; align-items:center; gap:11px; text-decoration:none; color:var(--on-dark)}
.brand-mark{width:30px; height:30px; flex:0 0 auto; color:var(--accent)}
.brand-name{font-family:var(--font-body); font-size:.95rem; letter-spacing:.17em; text-transform:uppercase; white-space:nowrap; font-weight:700}
.nav{display:flex; align-items:center; gap:clamp(18px,2.2vw,34px)}
.nav a{
  position:relative; text-decoration:none; color:var(--on-dark);
  font-size:.82rem; font-weight:600; letter-spacing:.15em; text-transform:uppercase;
  padding-block:6px; transition:color .35s var(--ease);
}
.nav a::after{
  content:""; position:absolute; left:0; bottom:0; height:1px; width:100%;
  background:var(--accent); transform:scaleX(0); transform-origin:left;
  transition:transform .45s var(--ease);
}
.nav a:hover{color:#fff}
.nav a[aria-current="page"]{color:#fff}
.nav a[aria-current="page"]::after{transform:scaleX(1)}
.nav a:hover::after{transform:scaleX(1)}
.hdr-call{
  display:inline-flex; align-items:center; gap:.55em; text-decoration:none; color:var(--on-dark);
  border:1px solid var(--line-dark); border-radius:var(--pill); padding:.62em 1.15em;
  font-size:.82rem; font-weight:600; white-space:nowrap;
  transition:border-color .4s var(--ease), background-color .4s var(--ease);
}
.hdr-call:hover{border-color:var(--on-dark); background:rgba(238,240,242,.08)}

/* The one filled control in the bar. Same destination as every other
   directions link on the site. */
.hdr-dirs{
  display:inline-flex; align-items:center; gap:.5em; white-space:nowrap;
  text-decoration:none; background:var(--accent-deep); color:#fff;
  border-radius:var(--pill); padding:.66em 1.2em;
  font-size:.82rem; font-weight:700; letter-spacing:.01em;
  transition:background-color .4s var(--ease);
}
.hdr-dirs:hover{background:#A63311}
.hdr-dirs .ar{transition:transform .4s var(--ease)}
.hdr-dirs:hover .ar{transform:translateX(3px)}
.burger{display:none; width:44px; height:44px; align-items:center; justify-content:center; margin-inline-end:-10px}
.burger span{display:block; width:22px; height:1.5px; background:var(--on-dark); position:relative; transition:background-color .2s var(--ease)}
.burger span::before,.burger span::after{content:""; position:absolute; left:0; width:22px; height:1.5px; background:var(--on-dark); transition:transform .45s var(--ease)}
.burger span::before{top:-7px}
.burger span::after{top:7px}
.burger[aria-expanded="true"] span{background:transparent}
.burger[aria-expanded="true"] span::before,.burger[aria-expanded="true"] span::after{background:var(--on-dark)}
.burger[aria-expanded="true"] span::before{transform:translateY(7px) rotate(45deg)}
.burger[aria-expanded="true"] span::after{transform:translateY(-7px) rotate(-45deg)}

/* Top-down full-screen drawer, house standard */
.drawer{
  position:fixed; inset-block-start:0; inset-inline:0; z-index:80;
  max-height:100svh; overflow-y:auto;
  background:var(--ground); padding:calc(var(--nav-h) + 22px) var(--gutter) 30px;
  border-bottom:1px solid var(--line-dark); box-shadow:var(--shadow-lg);
  transform:translateY(-101%); transition:transform .58s var(--ease), visibility .58s; visibility:hidden;
}
.drawer.is-open{transform:none; visibility:visible}
/* Direct children only. Scoping this to `.drawer a` would also capture the
   two buttons in the footer and beat their own colour and size rules. */
.drawer > a{
  display:block; text-decoration:none; color:var(--on-dark); font-family:var(--font-body); font-weight:700;
  letter-spacing:-.02em;
  font-size:clamp(1.45rem,1.2rem + 1.6vw,2rem); padding-block:.42em; border-bottom:1px solid var(--line-dark);
}
.drawer-foot{margin-top:26px; display:flex; flex-direction:column; gap:10px}
.drawer-foot .btn{justify-content:center}

/* ══ HERO - split. Same geometry the owner signed off on, inverted:
      the copy column is white and the photography panel carries the
      colour. The page opens on product, and on daylight. ══ */
.hero{position:relative; display:grid; grid-template-columns:1fr; min-height:calc(100svh - var(--nav-h)); margin-block-start:var(--nav-h)}
.hero > *{min-height:0; min-width:0}
.hero-copy{
  position:relative; z-index:2; display:flex; flex-direction:column; justify-content:center;
  padding:clamp(28px,4vw,56px) var(--gutter) clamp(28px,4vw,52px);
  background:var(--panel); color:var(--ink);
}
.hero-copy-in{position:relative; z-index:1; width:100%; max-width:42rem; margin-inline:auto}
.hero .eyebrow{margin-bottom:clamp(20px,3vw,30px); color:var(--accent-deep)}
.hero h1{margin-bottom:clamp(18px,2.4vw,26px); font-size:clamp(2.05rem,1.35rem + 2.6vw,3.25rem)}
.hero-lead{
  display:flex; flex-direction:column; gap:clamp(12px,1.4vw,18px);
  margin-bottom:clamp(26px,3.4vw,36px);
}
.hero .lead{max-width:40ch; margin:0; color:var(--ink-2)}
.hero .lead + .lead{font-size:clamp(.98rem,.95rem + .2vw,1.08rem)}
.hero-actions{display:flex; flex-wrap:wrap; align-items:center; gap:14px 22px}
.hero-media{position:relative; overflow:hidden; background:var(--sand); min-height:34svh}
/* Taken out of flow so the portrait crop cannot drive the hero taller than
   the viewport. The panel is sized by the grid row, the image fills it. */
.hero-media picture{position:absolute; inset:0; display:block}
.hero-media img{width:100%; height:100%; object-fit:cover; object-position:50% 50%}
/* No feather between the copy column and the plate: a clean edge. The
   gradient that used to sit here washed the left of the photograph and read
   as a glow coming off the white. The mobile rule below still scrims the
   plate, because there the copy sits on top of it. */
.hero-media::after{content:none}
/* The warm smoke plate that sat behind the copy is gone with the old
   palette. Nothing replaces it: the white column is the point. */
.hero-haze{display:none}

/* The directions link's own label styling, shared by both map components. */
.hero-map-cta{
  display:inline-flex; align-items:center; gap:.5em; white-space:nowrap;
  font-size:.78rem; font-weight:700; letter-spacing:.03em; color:var(--accent);
}

/* Live open/closed readout. The signature detail: it reads the shop's own
   clock in America/Phoenix, not the visitor's. */
/* The hero's footer line: opening state on the left, the Google rating on
   the right. One rule under both rather than two stacked rows. */
.hero-meta{
  display:flex; flex-wrap:wrap; align-items:center; gap:10px clamp(20px,2.6vw,34px);
  margin-top:clamp(28px,3.6vw,40px); padding-top:clamp(20px,2.6vw,26px);
  border-top:1px solid var(--line);
}
.status{
  display:inline-flex; align-items:center; gap:.7em;
  font-size:.82rem; letter-spacing:.03em; color:var(--ink-2);
}
.hero-rating{display:inline-flex; align-items:center; gap:.6em; font-size:.82rem; color:var(--ink-2)}
.hero-rating-g{width:15px; height:15px; flex:0 0 auto}
.hero-stars{display:inline-flex; gap:3px; color:var(--accent-deep)}
.hero-stars span{
  width:13px; height:13px; background:currentColor;
  -webkit-mask:var(--star) center/contain no-repeat; mask:var(--star) center/contain no-repeat;
}
.hero-rating-txt strong{color:var(--ink); font-weight:700}
.hero-rating-n{color:var(--muted)}
html:not(.js) .status{display:none}
.status-dot{width:7px; height:7px; border-radius:50%; background:var(--muted); flex:0 0 auto}
.status.is-open .status-dot{background:#2F8A4E; animation:pulse 2.6s var(--ease) infinite}
.status-label{font-weight:700; color:var(--ink)}
.status-sep{margin-inline:.5em; color:var(--muted)}
@keyframes pulse{0%,100%{opacity:1; transform:scale(1)} 50%{opacity:.4; transform:scale(.8)}}

/* ══ STATEMENT ════════════════════════════════════════════════ */
.statement{display:grid; grid-template-columns:1fr; gap:clamp(28px,4vw,64px)}
.statement-body{display:flex; flex-direction:column; gap:16px; color:var(--ink-2); max-width:56ch}
/* Spans both text columns: the section says who and what, then shows where. */
.statement-map{grid-column:1/-1; margin-top:clamp(6px,1.5vw,18px)}
.statement-map .map-frame{min-height:clamp(230px,26vw,330px)}

/* ══ CATEGORY MOSAIC ══════════════════════════════════════════ */
.mosaic{display:grid; grid-template-columns:repeat(12,1fr); border-block-start:1px solid var(--line)}
.tile{
  position:relative; overflow:hidden; padding:clamp(28px,3.4vw,52px);
  min-height:clamp(258px,29vw,372px); display:flex; flex-direction:column; justify-content:flex-end;
  border-inline-end:1px solid var(--line); border-block-end:1px solid var(--line);
  transition:background-color .5s var(--ease);
}
.tile-5{grid-column:span 5}
.tile-7{grid-column:span 7}
.tile-12{grid-column:span 12}
.tile-dark{background:var(--ground); color:var(--on-dark)}
.tile-raised{background:var(--ground-2); color:var(--on-dark)}
.tile-ember{background:var(--ember); color:var(--on-dark)}
/* Light tiles. Two of the six categories have no photography yet, so
   they are designed as type rather than dressed in a stock picture of
   something the shop may not stock. */
.tile-light{background:var(--panel); color:var(--ink)}
.tile-tint{background:var(--sand); color:var(--ink)}
.tile-light .tile-eyebrow,.tile-tint .tile-eyebrow{color:var(--accent-deep)}
.tile-light p,.tile-tint p{color:var(--ink-2)}
.tile-light .eyebrow,.tile-tint .eyebrow{color:var(--accent-deep)}
.tile-dark:not(.tile-intro):hover,.tile-raised:hover,.tile-ember:hover{background:var(--ground-3)}
.tile-tint:hover{background:#E3E0DA}
/* The categories with no photography carry the number at display size
   instead, so they read as designed rather than as a tile someone forgot
   to fill. Decorative: the heading underneath still names the category. */
.tile-plain .tile-eyebrow{
  font-size:clamp(3.6rem,6.4vw,5.6rem); line-height:.78; letter-spacing:-.045em;
  font-weight:700; color:var(--accent-deep); opacity:.28; margin-bottom:auto;
}
.tile-plain h3{margin-top:14px}
.tile-intro{justify-content:center}
.tile-intro h2{margin-bottom:18px}
.tile-eyebrow{
  position:relative; z-index:1;
  font-size:.66rem; font-weight:700; letter-spacing:.2em; text-transform:uppercase;
  color:var(--on-dark-3); margin-bottom:auto;
}
.tile h3{position:relative; z-index:1; margin-bottom:10px}
.tile-photo .tile-eyebrow{color:var(--on-dark-2)}
.tile p{position:relative; z-index:1; font-size:.94rem; line-height:1.6; color:var(--on-dark-2); max-width:34ch}
/* Photographic plate behind a category tile. The image is taken out of flow so
   it cannot drive the tile height, and a bottom-weighted scrim keeps the copy
   legible over whatever the photograph is doing underneath it. */
.tile-plate{position:absolute; inset:0; z-index:0; display:block; overflow:hidden}
.tile-plate img{
  width:100%; height:100%; object-fit:cover;
  transition:transform .9s var(--ease);
}
.tile-photo::after{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:linear-gradient(180deg,rgba(18,21,24,.16) 0%,rgba(18,21,24,.4) 42%,rgba(18,21,24,.86) 100%);
}
/* A photographic tile that stays light. The scrim runs the other way and
   the type is ink, for plates that are bright enough to carry it. */
.tile-photo-light{background:var(--sand); color:var(--ink)}
.tile-photo-light::after{
  background:linear-gradient(180deg,rgba(255,255,255,.06) 0%,rgba(255,255,255,.5) 42%,rgba(255,255,255,.93) 100%);
}
.tile-photo-light .tile-eyebrow{color:var(--accent-deep)}
.tile-photo-light p{color:var(--ink-2)}
.tile-photo-light:hover{background:var(--sand)}

/* The cigar tile keeps a warm scrim, matching the strip. */
.tile-ember.tile-photo::after{
  background:linear-gradient(180deg,rgba(28,18,13,.2) 0%,rgba(28,18,13,.44) 42%,rgba(28,18,13,.88) 100%);
}
.tile-photo:hover .tile-plate img{transform:scale(1.05)}

/* The two warm haze plates went with the old palette. A hairline ember
   wash in the corner does the same job on a light tile. */
.tile-haze{
  position:absolute; inset:0; z-index:0; pointer-events:none;
  background:radial-gradient(ellipse 60% 70% at 100% 0%,rgba(196,63,22,.10) 0%,rgba(196,63,22,0) 68%);
}

/* ══ THE SHOP ═════════════════════════════════════════════════ */
/* The cigar side of the shop, kept deliberately warm and dark. It is the
   only place on the page that still looks like the old direction, and
   that is the point: the humidor gets its own moment, then the page
   returns to daylight. */
.strip{position:relative; overflow:hidden; background:var(--ember)}
.strip::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(ellipse 62% 88% at 50% 50%,rgba(24,16,12,.86) 0%,rgba(24,16,12,.64) 58%,rgba(24,16,12,.78) 100%);
}
.strip img{width:100%; aspect-ratio:3.4/1; object-fit:cover; min-height:230px}
.strip-copy{position:absolute; z-index:1; inset:0; display:grid; place-items:center; padding:clamp(24px,3.4vw,44px) 0}
.strip-copy-in{width:min(100% - var(--gutter)*2,var(--wide)); margin-inline:auto; display:flex; justify-content:center}
.strip-card{max-width:46ch; color:var(--on-dark); text-align:center}
.strip-card .eyebrow{color:var(--warm); margin-bottom:14px; justify-content:center}
.strip-card .eyebrow::before{content:""; flex:0 0 44px; height:1px; background:currentColor; opacity:.45}
.strip-card h2{margin-bottom:12px; font-family:var(--font-display); font-weight:500; letter-spacing:-.008em}
.strip-card p{color:var(--on-dark-2); font-size:.98rem; line-height:1.62}

.shop-layout{display:grid; grid-template-columns:1fr; gap:clamp(30px,4vw,64px); align-items:center}
.shop-layout .band-head{margin-bottom:0}

/* Slideshow. One frame at a time rather than the whole set, so the two
   photographs still to be shot do not dominate the section. */
.shop-stage{position:relative; overflow:hidden; border-radius:var(--radius); background:var(--ground-2); aspect-ratio:4/3}
/* Scoped to the stage so it outranks .slot's own position, which is
   declared later in this file for the no-script stacked layout. */
.shop-stage .slide{position:absolute; inset:0; margin:0; opacity:0; transition:opacity .9s var(--ease)}
.shop-stage .slide.is-active{opacity:1}
.shop-stage .slide.slot{aspect-ratio:auto; border-radius:0; border-width:0}
.shot{position:relative; overflow:hidden; background:var(--ground-2)}
.shot picture{position:absolute; inset:0; display:block}
.shot img{width:100%; height:100%; object-fit:cover}
html:not(.js) .shot picture{position:relative}
/* With no script every frame simply stacks, so nothing is hidden. */
html:not(.js) .shop-stage{aspect-ratio:auto; display:grid; gap:16px; background:none; overflow:visible}
html:not(.js) .shop-stage .slide{position:relative; opacity:1; aspect-ratio:16/10; border-radius:var(--radius); overflow:hidden}
html:not(.js) .shop-stage .slide.slot{border-width:1px}

.shop-controls{display:flex; align-items:center; gap:18px; margin-top:18px}
html:not(.js) .shop-controls{display:none}
.shop-count{font-size:.72rem; font-weight:700; letter-spacing:.18em; color:var(--muted); font-variant-numeric:tabular-nums}
.shop-dots{display:flex; gap:8px; margin-inline-start:auto}
.shop-dots button{
  width:34px; height:34px; display:grid; place-items:center; border-radius:50%;
}
.shop-dots button::after{
  content:""; width:7px; height:7px; border-radius:50%; background:rgba(23,25,28,.26);
  transition:background-color .4s var(--ease), transform .4s var(--ease);
}
.shop-dots button[aria-current="true"]::after{background:var(--accent-deep); transform:scale(1.35)}
.shot-cap{
  position:absolute; inset-block-end:0; inset-inline:0; padding:44px 22px 18px;
  font-size:.78rem; letter-spacing:.03em; color:var(--on-dark);
  background:linear-gradient(180deg,rgba(22,25,28,0),rgba(22,25,28,.85));
}
/* Designed photography placeholder. Not a grey box: it states what belongs
   in the frame so the client can brief the shoot from the page itself.

   Nothing wears this at the moment - the shop slideshow dropped its two
   remaining slots and is five real photographs now. Kept because the two
   shots it was standing in for still have not been taken, and the brief
   for them is in index.html beside where these used to sit. */
.slot{
  position:relative; overflow:hidden; border-radius:var(--radius);
  border:1px dashed rgba(23,25,28,.26); background:var(--panel);
  aspect-ratio:16/10; display:flex; flex-direction:column; justify-content:flex-end;
  padding:clamp(18px,2.2vw,26px); color:var(--ink);
}
.slot-orn{
  position:absolute; inset-block-start:-16%; inset-inline-end:-8%;
  width:60%; aspect-ratio:1; opacity:.17; color:var(--accent-deep);
  background:currentColor; pointer-events:none;
  -webkit-mask:url(marks/orn.svg) center/contain no-repeat;
  mask:url(marks/orn.svg) center/contain no-repeat;
}
.slot-tag{
  position:relative; z-index:1;
  font-size:.6rem; font-weight:700; letter-spacing:.2em; text-transform:uppercase;
  color:var(--accent-deep); margin-bottom:auto;
}
.slot-name{position:relative; z-index:1; font-weight:700; letter-spacing:-.018em; font-size:clamp(1.05rem,.98rem + .4vw,1.28rem); line-height:1.15; margin-bottom:5px}
.slot-note{position:relative; z-index:1; font-size:.8rem; line-height:1.5; color:var(--muted)}

/* ══ BRANDS + SOCIAL PROOF SLOTS ══════════════════════════════ */
.brand-grid{
  display:grid; grid-template-columns:repeat(2,1fr);
  gap:1px; background:var(--line); border:1px solid var(--line); margin-top:clamp(28px,4vw,44px);
}
.brand-cell{
  background:var(--panel); min-height:106px; display:grid; place-items:center; text-align:center;
  padding:20px 16px; font-family:var(--font-body); font-size:.95rem; letter-spacing:.09em;
  text-transform:uppercase; color:var(--muted); font-weight:500;
}
.brand-cell.is-slot{
  color:rgba(110,117,123,.7); font-family:var(--font-body); font-size:.72rem;
  letter-spacing:.16em; font-weight:600;
}
.proof{
  margin-top:clamp(44px,6vw,80px); padding-top:clamp(34px,4.4vw,52px); border-top:1px solid var(--line);
  display:grid; grid-template-columns:1fr; gap:clamp(20px,3vw,40px); justify-items:center;
}
.proof-head{grid-column:1/-1; max-width:44rem}
.proof-head .eyebrow{margin-bottom:14px}
.proof-slot{
  border:1px dashed rgba(23,25,28,.26); border-radius:var(--radius); background:var(--panel);
  padding:clamp(22px,2.8vw,34px); display:flex; flex-direction:column; gap:14px; min-height:184px;
}
/* A real, attributable review. One card, centred: the shop has one, and a
   second empty slot beside it would advertise the fact. */
.proof-card{
  margin:0; max-width:44rem; text-align:center;
  border:1px solid var(--line); border-radius:var(--radius); background:var(--panel);
  padding:clamp(26px,3.4vw,42px) clamp(22px,3vw,40px);
  display:flex; flex-direction:column; align-items:center; gap:16px;
}
.proof-card .proof-body{
  font-style:normal; color:var(--ink); font-size:clamp(1.02rem,.97rem + .32vw,1.24rem);
  line-height:1.55; margin:0;
}
.proof-card .proof-attr{
  margin:0; color:var(--muted); font-size:.7rem; letter-spacing:.18em;
}
.proof-stars{display:flex; gap:5px; color:rgba(23,25,28,.2)}
.proof-stars.is-filled{color:var(--accent-deep)}
.proof-stars span{
  width:15px; height:15px; background:currentColor;
  -webkit-mask:var(--star) center/contain no-repeat; mask:var(--star) center/contain no-repeat;
}
.proof-body{color:var(--muted); font-size:.9rem; line-height:1.6; font-style:italic}
.proof-attr{margin-top:auto; font-size:.72rem; font-weight:600; letter-spacing:.16em; text-transform:uppercase; color:rgba(110,117,123,.75)}

/* ══ VISIT ════════════════════════════════════════════════════ */
.visit{display:grid; grid-template-columns:1fr; gap:clamp(34px,4.5vw,64px)}
.spec{border-block-start:1px solid var(--line-dark)}
.spec-row{
  display:grid; grid-template-columns:1fr; gap:4px 28px;
  padding-block:clamp(15px,1.8vw,21px); border-block-end:1px solid var(--line-dark);
}
.spec-k{font-size:.65rem; font-weight:700; letter-spacing:.2em; text-transform:uppercase; color:var(--on-dark-3); padding-top:.4em}
.spec-v{color:var(--on-dark); font-size:.98rem; line-height:1.6}
.spec-v a{text-decoration:none; border-bottom:1px solid var(--line-dark); transition:border-color .35s var(--ease)}
.spec-v a:hover{border-bottom-color:var(--accent)}
.hours{display:grid; gap:7px; margin:0}
.hours > div{display:flex; justify-content:space-between; gap:20px; max-width:22rem}
.hours dt{color:var(--on-dark-2)}
.hours dd{margin:0; font-variant-numeric:tabular-nums}
.hours .is-today dt,.hours .is-today dd{color:var(--accent); font-weight:700}
.visit-actions{display:flex; flex-wrap:wrap; gap:12px; margin-top:clamp(26px,3.4vw,36px)}
/* The product-assistance band. Centred under a centred head, and stacked
   full width on a phone so neither button ends up a thumb-width target
   floating beside the other. */
.help-actions{display:flex; flex-wrap:wrap; justify-content:center; gap:12px 16px}
@media (max-width:620px){
  .help-actions{flex-direction:column; align-items:stretch}
  .help-actions .btn{justify-content:center}
}
/* Static map placeholder. A live embed would add a third-party request and a
   cookie surface to a page whose address is not final. */
/* Same component as the hero map, at section scale. */
.map{
  position:relative; border-radius:var(--radius); overflow:hidden;
  background:var(--ground-2); border:1px solid var(--line-dark);
  display:flex; flex-direction:column;
}
.map-frame{
  display:block; width:100%; border:0; flex:1 1 auto;
  min-height:clamp(240px,28vw,340px); background:var(--ground-2);
}
.map-bar{
  display:flex; align-items:flex-start; justify-content:space-between; gap:18px;
  padding:clamp(18px,2.2vw,24px); text-decoration:none; color:var(--on-dark);
  border-top:1px solid var(--line-dark); background:var(--ground);
  transition:background-color .4s var(--ease);
}
.map-bar:hover{background:var(--ground-3)}
.map-bar .ar{transition:transform .4s var(--ease)}
.map-bar:hover .ar{transform:translateX(4px)}
.map-bar .hero-map-cta{padding-top:3px}
.map-note{position:relative; color:var(--on-dark-3); font-size:.8rem; line-height:1.55}
.map-note strong{display:block; color:var(--on-dark); font-weight:700; font-size:1.08rem; letter-spacing:-.016em; margin-bottom:5px}

/* The address in the visit table is itself the maps button. */
.spec-map{
  display:flex; flex-wrap:wrap; align-items:baseline; gap:6px 18px;
  text-decoration:none; border-bottom:0 !important;
}
.spec-map-cta{
  display:inline-flex; align-items:center; gap:.45em; white-space:nowrap;
  font-size:.72rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--accent);
}
.spec-map .ar{transition:transform .4s var(--ease)}
.spec-map:hover .ar{transform:translateX(4px)}
.spec-map:hover span:first-child{text-decoration:underline; text-underline-offset:3px}

/* ══ FOOTER ═══════════════════════════════════════════════════ */
.foot{background:var(--ground-2); color:var(--on-dark); padding-block:clamp(54px,7vw,86px) 32px}
.foot-top{
  display:grid; grid-template-columns:1fr; gap:clamp(30px,4vw,56px);
  padding-bottom:clamp(34px,4.4vw,52px); border-bottom:1px solid var(--line-dark);
}
.foot .foot-h{font-size:.65rem; font-weight:700; letter-spacing:.2em; text-transform:uppercase; color:var(--on-dark-3); font-family:var(--font-body); margin-bottom:16px}
.foot-links{display:grid; gap:9px}
.foot-links a{text-decoration:none; color:var(--on-dark-2); font-size:.92rem; transition:color .35s var(--ease)}
.foot-links a:hover{color:var(--on-dark)}
.foot .brand{color:var(--on-dark)}
.foot .brand-mark{color:var(--accent)}
.foot-brand .brand-name{font-size:1.02rem}
.foot-blurb{color:var(--on-dark-3); font-size:.88rem; line-height:1.65; max-width:32ch; margin-top:16px}
/* Compliance block. Every line here is a marked placeholder: the client's
   own counsel supplies the final wording. */
.legal{
  margin-top:clamp(30px,3.6vw,44px); padding:clamp(22px,2.6vw,30px);
  border:1px solid var(--line-dark); border-radius:var(--radius); background:rgba(238,240,242,.03);
}
.legal-tag{font-size:.6rem; font-weight:700; letter-spacing:.2em; text-transform:uppercase; color:var(--accent); margin-bottom:14px}
.legal p{color:var(--on-dark-2); font-size:.82rem; line-height:1.7; max-width:84ch}
.legal p + p{margin-top:10px}
.legal .ph{color:var(--on-dark-3); font-style:italic}
.foot-base{
  display:flex; flex-wrap:wrap; gap:10px 26px; justify-content:space-between; align-items:center;
  padding-top:26px; color:var(--on-dark-3); font-size:.78rem;
}
.foot-base a{color:var(--on-dark-2); text-decoration:none}
.foot-base a:hover{color:var(--on-dark)}

/* ══ FIXED MOBILE CALL BAR ════════════════════════════════════ */
.callbar{position:fixed; inset-inline:0; inset-block-end:0; z-index:70; display:none; background:var(--accent-deep); color:#fff}
.callbar a{
  display:flex; align-items:center; justify-content:center; gap:.6em; min-height:56px;
  text-decoration:none; font-weight:700; font-size:1rem; letter-spacing:.02em;
}

/* ══ REVEALS - gated behind html.js so no-JS shows everything ══ */
html.js .reveal{opacity:0; transform:translateY(22px); transition:opacity .82s var(--ease), transform .82s var(--ease)}
html.js .reveal.is-in{opacity:1; transform:none}

/* ══════════════════════════════════════════════════════════════
   BREAKPOINT LADDER - 1180 / 1080 / 900 / 760 / 620
   ══════════════════════════════════════════════════════════════ */
@media (min-width:761px){
  .statement{grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:clamp(40px,5vw,90px)}
  .spec-row{grid-template-columns:168px 1fr}
  .foot-top{grid-template-columns:1.6fr 1fr 1fr}
  /* Four columns so the eight cells fill two whole rows and the grid gap
     never shows through an empty tail. */
  .brand-grid{grid-template-columns:repeat(4,1fr)}
}
@media (min-width:901px){
  .shop-layout{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .hero{grid-template-columns:minmax(0,1.02fr) minmax(0,.98fr)}
  .hero-media{min-height:0}
  .visit{grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr); align-items:start}
}
@media (min-width:1081px){
  .shop-layout{grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr)}
}

/* Nav collapses to the drawer */
@media (max-width:1180px){
  .nav{display:none}
  .burger{display:flex}
  .hdr-call{display:none}
}
@media (max-width:620px){
  .hdr-dirs{padding:.58em .9em; font-size:.76rem; gap:.4em}
  .hdr-dirs .ar{display:none}
}
@media (max-width:360px){
  .hdr-dirs{display:none}
}
@media (max-width:900px){
  :root{--nav-h:66px}

  /* The per-page header inversion that used to live here is gone: the bar is
     solid dark everywhere now, so there is nothing to flip.

  /* One photograph behind everything, copy anchored to the bottom over it.
     Simpler than a band of image above a band of type, and it lets the
     portrait plate do the work on a phone-shaped screen. */
  /* One column: the copy sits over the photograph. Grid overlap rather than
     an absolute plate, so both share the single row. */
  .hero{grid-template-columns:1fr; grid-template-rows:minmax(min-content,1fr)}
  .hero-media{position:relative; grid-row:1; grid-column:1; z-index:0; min-height:0}
  /* The plate is a room, not a subject: enough scrim that it reads as
     ground for the type, not so much that the shelving disappears. */
  .hero-media::after{
    content:""; position:absolute; inset:0; pointer-events:none;
    background:linear-gradient(180deg,rgba(18,21,24,.9) 0%,rgba(18,21,24,.8) 30%,
      rgba(18,21,24,.68) 54%,rgba(18,21,24,.64) 72%,rgba(18,21,24,.88) 100%);
  }
  .hero-copy{
    position:relative; grid-row:1; grid-column:1;
    z-index:2; background:none; color:var(--on-dark); justify-content:flex-start;
    /* The map row now sits under this, and the fixed call bar is cleared by
       the body's own bottom padding, so the copy no longer reserves for it. */
    padding-block:clamp(20px,4vw,32px) clamp(18px,3vw,26px);
  }

  /* Four zones rather than one undifferentiated run of text: a status
     readout, the label, the statement, the action. Same shape as the house
     mobile hero on Noll. */
  .hero-copy-in{display:flex; flex-direction:column; align-items:stretch; max-width:34rem}
  .hero-meta{
    order:1; width:100%; gap:8px 18px;
    margin:0 0 24px; padding:0 0 14px;
    border-top:0; border-bottom:1px solid var(--line-dark);
  }
  .status{font-size:.78rem}
  .status.is-open .status-dot{background:#5FD08A}
  .hero-rating{font-size:.78rem; color:var(--on-dark-2)}
  .hero-rating-txt strong{color:var(--on-dark)}
  .hero-rating-n{color:var(--on-dark-3)}
  .hero-stars{color:var(--accent)}
  .hero .eyebrow{
    order:2; margin:0 0 13px; font-size:.62rem; letter-spacing:.15em; line-height:1.4;
    color:var(--accent);
  }
  .hero .lead{color:var(--on-dark-2)}
  .hero-meta{border-color:var(--line-dark)}
  .status{color:var(--on-dark-2)}
  .status-label{color:var(--on-dark)}
  .status-sep{color:var(--on-dark-3)}
  .hero .eyebrow::after{display:none}
  .hero h1{order:3; margin:0 0 15px; font-size:clamp(2.2rem,1.5rem + 3.4vw,2.9rem)}
  .hero-lead{order:4; margin:0; gap:10px}
  .hero .lead{font-size:1rem; line-height:1.55; max-width:34ch}
  .hero .lead + .lead{font-size:.94rem}
  .hero-actions{order:5; margin-top:26px}
  .hero-haze{display:none}
  .tile-5,.tile-7{grid-column:span 6}
}
@media (max-width:760px){
  /* The copy stays over the photograph rather than dropping below it, with a
     heavier scrim doing the legibility work. */
  .strip img{aspect-ratio:5/4; min-height:0; object-position:26% center}
  .strip::after{
    background:linear-gradient(180deg,rgba(24,16,12,.55) 0%,rgba(24,16,12,.74) 42%,rgba(24,16,12,.86) 100%);
  }
  .strip-card .eyebrow{flex-wrap:wrap; row-gap:8px}
  .strip-copy{padding:var(--gutter)}
  .strip-copy-in{width:100%}
  .strip-card{max-width:none}
}
@media (max-width:620px){
  :root{--callbar-h:56px}
  /* The fixed call bar overlays the foot of the hero, so reserve its height
     inside the hero rather than letting it sit on the copy. */
  .hero{padding-bottom:var(--callbar-h)}
  .brand-grid{grid-template-columns:repeat(2,1fr)}
  body{padding-bottom:var(--callbar-h)}
  .callbar{display:block}
  .tile-5,.tile-7{grid-column:span 12}
  .tile{min-height:clamp(230px,58vw,300px); padding-block:clamp(34px,7vw,46px)}
  .hero-actions{flex-direction:column; align-items:stretch; gap:10px}
  .hero-actions .btn{justify-content:center}
  /* The fixed call bar sits directly beneath this, so a second identical
     call link here is pure duplication. */
  .hero-actions .arrow-link{display:none}
  .visit-actions{flex-direction:column}
  .visit-actions .btn{justify-content:center}
  .gate-actions{flex-direction:column}
  .gate-actions .btn{width:100%}
  /* Full-bleed imagery on phones, house pattern */
  .strip{width:100vw; margin-inline:calc(50% - 50vw)}
  .hours > div{max-width:none}
}

/* Short phones. The hero is one screen everywhere else; on a 640px-tall
   handset the copy needs the image row and the type to give ground. */
/* Short phones. The hero is a single full-bleed plate now, so this only has
   to tighten the stack; the old two-row grid override belonged to the
   previous layout and was starving the copy of its row. */
@media (max-width:620px) and (max-height:810px){
  .hero h1{font-size:clamp(1.95rem,1.5rem + 2.2vw,2.4rem); margin-bottom:12px}
  .hero .lead{font-size:.94rem; line-height:1.5; max-width:36ch}
  .hero .lead + .lead{font-size:.88rem}
  .hero .eyebrow{margin-bottom:10px; font-size:.58rem}
  .hero-meta{margin-bottom:16px; padding-bottom:11px}
  .status,.hero-rating{font-size:.75rem}
  .hero-actions{margin-top:20px}
}

/* ══ REDUCED MOTION - honoured, never defeated ════════════════ */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important; scroll-behavior:auto !important;
  }
  html.js .reveal{opacity:1; transform:none}
  .btn:hover{transform:none}
  .tile-photo:hover .tile-plate img{transform:none}
  .status.is-open .status-dot{animation:none}
}

/* ══════════════════════════════════════════════════════════════════
   PRODUCTS PAGE
   A catalogue grid, not a store. There is no price, no cart and no
   buy control anywhere in here, because nothing is sold through the
   site: the page exists so someone can decide whether the trip is
   worth making. The hairline grid is the same device the brand strip
   and the mosaic use, at card scale.
   ══════════════════════════════════════════════════════════════════ */
/* The band already pads more than the fixed header is tall, so this only
   has to add breathing room, not clear the header a second time. It used to
   clear it twice over, which was invisible under a title and a paragraph and
   became a hole once the paragraph came out. */
.page-head{max-width:46rem; padding-block:calc(var(--nav-h) * .5 + clamp(10px,2vw,22px)) 0}
/* The page title is the only thing in this block now, so it carries the
   weight the eyebrow and lead used to share. */
.page-head h1{
  margin:0 0 18px; font-size:clamp(2.6rem,1.8rem + 3.4vw,4.4rem);
  line-height:.98; letter-spacing:-.034em;
}
/* Label text that only the screen reader needs - the search field's, whose
   purpose the placeholder and the magnifier already carry visually. */
.vh{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}
.page-actions{display:flex; flex-wrap:wrap; align-items:center; gap:14px 22px; margin-top:clamp(24px,3vw,32px)}

/* ══ CATALOGUE LAYOUT ══════════════════════════════════════════════
   Departments down the left, goods on the right - the arrangement every
   catalogue with more than a screenful of categories converges on, and
   the one the smoke shops all use. Sixteen categories laid out as a
   wrapping row of pills was three rows of shouting capitals that pushed
   the products off the first screen; as a list they read in one pass and
   can carry their line counts. The column is sticky, so changing your
   mind never costs a scroll back to the top.
   ══════════════════════════════════════════════════════════════════ */
/* minmax(0,1fr), not 1fr: below the sidebar breakpoint the rail becomes a
   horizontal scroller, and a plain `1fr` track takes its automatic minimum
   from the item's min-content - which here is all seventeen chips laid end to
   end. The track grew to 3200px and took the whole page sideways with it. */
.cat-layout{
  display:grid; grid-template-columns:minmax(0,1fr); gap:clamp(20px,2.4vw,30px);
  margin-block-start:clamp(24px,3vw,38px);
}
@media (min-width:1000px){
  .cat-layout{
    grid-template-columns:15.5rem minmax(0,1fr);
    gap:clamp(30px,3.2vw,52px); align-items:start;
  }
  .cat-side{position:sticky; inset-block-start:calc(var(--nav-h) + 20px)}
  /* Its own scrollbar rather than the page's, so a short viewport can still
     reach Sundries without scrolling the grid away. */
  .cat-side-in{
    max-height:calc(100svh - var(--nav-h) - 40px); overflow-y:auto;
    overscroll-behavior:contain; padding-inline-end:4px;
    scrollbar-width:thin; scrollbar-color:var(--line) transparent;
  }
}
/* Without script there is nothing to filter with, so the controls take
   themselves off the page and every category is simply listed. */
html:not(.js) .cat-side{display:none}

/* ── search ──────────────────────────────────────────────────── */
.cat-search{
  position:relative; display:flex; align-items:center;
  background:var(--panel); border:1px solid var(--line); border-radius:10px;
  transition:border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.cat-search:focus-within{border-color:var(--ink); box-shadow:var(--shadow-sm)}
.cat-search-i{
  flex:0 0 auto; width:17px; height:17px; margin-inline:12px 0; color:var(--muted);
}
.cat-search input{
  flex:1 1 auto; min-width:0; border:0; background:none; outline:none;
  padding:.78em .5em .78em .6em; font:inherit; font-size:.86rem; color:var(--ink);
}
.cat-search input::placeholder{color:var(--muted)}
/* Safari draws its own clear button; ours is the one that resets the view. */
.cat-search input::-webkit-search-cancel-button{display:none}
.cat-x{
  flex:0 0 auto; display:grid; place-items:center; width:30px; height:30px;
  margin-inline-end:5px; border-radius:7px; color:var(--muted);
  transition:background-color .25s var(--ease), color .25s var(--ease);
}
.cat-x svg{width:15px; height:15px}
.cat-x:hover{background:rgba(23,25,28,.07); color:var(--ink)}
/* display:grid above outranks the [hidden] default, so say it. */
.cat-x[hidden]{display:none}

/* ── filter rail ─────────────────────────────────────────────── */
.cat-rail{display:flex; flex-direction:column; gap:2px; margin-block-start:14px}
.cat-chip{
  display:flex; align-items:center; gap:10px; width:100%; text-align:start;
  border:1px solid transparent; border-radius:8px; padding:.56em .7em;
  font-size:.82rem; font-weight:600; letter-spacing:-.005em; line-height:1.3;
  color:var(--ink-2); background:none;
  transition:background-color .25s var(--ease), color .25s var(--ease);
}
.cat-chip-t{flex:1 1 auto; min-width:0}
/* Tabular, so the column of counts lines up instead of shimmering. */
.cat-chip-n{
  flex:0 0 auto; font-size:.68rem; font-weight:700; color:var(--muted);
  font-variant-numeric:tabular-nums;
}
.cat-chip:hover{background:rgba(23,25,28,.05); color:var(--ink)}
.cat-chip[aria-pressed="true"]{background:var(--ink); color:var(--bg); font-weight:700}
.cat-chip[aria-pressed="true"] .cat-chip-n{color:rgba(255,255,255,.62)}
/* Where you are while reading everything, as distinct from what you have
   chosen. A scroll position is not a selection, so it is a mark and not a
   fill. */
.cat-chip.is-here:not([aria-pressed="true"]){color:var(--ink); background:rgba(23,25,28,.045)}
.cat-chip.is-here:not([aria-pressed="true"]) .cat-chip-t{
  box-shadow:inset 0 -1px 0 var(--accent-deep);
}
/* A count of zero during a search: still reachable, visibly not worth it. */
.cat-chip.is-empty:not([aria-pressed="true"]){opacity:.38}

/* ── result line ─────────────────────────────────────────────── */
.cat-status{
  margin-bottom:clamp(16px,1.8vw,22px); padding-bottom:clamp(14px,1.6vw,18px);
  border-bottom:1px solid var(--line);
  font-size:.78rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  color:var(--muted); font-variant-numeric:tabular-nums;
}
.cat-status b{color:var(--ink); font-weight:700}
.cat-status em{font-style:normal; color:var(--accent-deep)}
html:not(.js) .cat-status{display:none}

/* ── nothing found ───────────────────────────────────────────── */
.cat-none{
  padding:clamp(34px,5vw,60px) 0 clamp(20px,3vw,30px); max-width:44ch;
}
.cat-none-h{font-size:1.15rem; font-weight:700; letter-spacing:-.02em; margin-bottom:10px}
.cat-none-h span{color:var(--accent-deep)}
.cat-none-p{font-size:.88rem; line-height:1.6; color:var(--muted); margin-bottom:20px}

/* ── category blocks ─────────────────────────────────────────── */
/* Spacing between blocks, not before the first one, and measured off the
   preceding *visible* block so a filtered view has no phantom gap at the
   top. Filtering hides blocks with [hidden], and a hidden sibling still
   counts for `+`, so the rule is written on the block itself and cleared
   when it is the first one showing. */
.cat-block{margin-top:clamp(46px,6vw,84px)}
.cat-block.is-first{margin-top:0}
.cat-block[hidden]{display:none}
.cat-head{
  display:flex; flex-wrap:wrap; align-items:baseline; gap:8px 20px;
  margin-bottom:clamp(18px,2.2vw,26px);
}
.cat-head h2{flex:0 0 auto}
.cat-blurb{flex:1 1 18rem; font-size:.9rem; line-height:1.55; color:var(--muted)}
.cat-count{
  font-size:.68rem; font-weight:700; letter-spacing:.16em; text-transform:uppercase;
  color:var(--accent-deep); font-variant-numeric:tabular-nums; white-space:nowrap;
}

/* ── the grid ────────────────────────────────────────────────── */
/* Separated cards on smaller tiles rather than one edge-to-edge hairline
   grid. Two things follow from the smaller card: the plate shrinks with it,
   so the low-resolution crops are scaled up far less and read sharper, and
   the grid stops looking like a spreadsheet. */
.pgrid{
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(10px,1.1vw,16px); background:none; border:0;
}
/* position:relative is load-bearing, not decoration. .pcard-open::after is
   absolutely positioned with inset:0 to make the whole card clickable, and
   without a positioned ancestor here it resolves against the viewport
   instead - 187 invisible full-page sheets stacked over the sidebar, so
   nothing else on the page could be clicked and every card opened whichever
   product came last in the markup. overflow:hidden below does not clip it
   either, because a box only clips descendants it is the containing block
   for. */
.pcard{
  position:relative;
  background:var(--panel); display:flex; flex-direction:column;
  padding-bottom:clamp(12px,1.2vw,16px);
  border:1px solid var(--line); border-radius:10px; overflow:hidden;
  transition:border-color .4s var(--ease), box-shadow .4s var(--ease), transform .4s var(--ease);
}
.pcard:hover{
  border-color:rgba(23,25,28,.26); box-shadow:var(--shadow-sm); transform:translateY(-2px);
}
/* The card sets display:flex, which outranks the [hidden] default of
   display:none. Searching hides individual cards, so this has to say so. */
.pcard[hidden]{display:none}
/* Square plate, so a portrait bong and a flat pack of papers sit on the
   same baseline without either being cropped through. */
/* White, not tinted. The crops carry the storefront's own white photo
   background, so any tint here would show as a rectangle behind each
   product. The category rhythm moved to the card foot instead. */
.pcard-plate{
  position:relative; aspect-ratio:1; display:grid; place-items:center;
  overflow:hidden; background:#fff;
}
/* Normalised on height, not on the frame. The crops came out of screenshots
   at anything from 25 to 152 real pixels tall, and letting each sit at its
   own size made the grid look broken. Height-matching costs some sharpness
   on the smallest ones; a consistent grid is worth more than that. */
/* The plate takes its height from aspect-ratio, which browsers treat as an
   indefinite height: a percentage height on the image inside collapses to
   auto. Taking the <picture> out of flow with inset:0 gives it a definite
   box, and the percentages below resolve against it. */
.pcard-plate picture{position:absolute; inset:0; display:grid; place-items:center}
/* Packshots are capped, not stretched: the sources range from 25 to 150 real
   pixels tall and matching them keeps the grid even. */
.pcard-plate img{
  width:auto; height:auto; max-width:84%; max-height:76%; object-fit:contain;
}
/* A shelf photograph is a scene, not a cutout, so it fills the plate. */
.pcard-plate.is-scene{background:var(--bg)}
/* Absolute against the plate itself. Sizing the image as a grid item inside
   <picture> left Chrome resolving its percentage height to auto; taking it
   out of flow against the positioned plate is unambiguous. */
.pcard-plate.is-scene img{
  position:absolute; inset:0; width:100%; height:100%;
  max-width:none; max-height:none; object-fit:cover;
}
/* Stand-in until the photography exists. Quiet on purpose: it should read
   as a plate waiting for a picture, not as a broken image. */
.pcard-mark{width:34%; max-width:62px; height:auto; color:var(--ink); opacity:.07}
/* Until real photography exists the plate carries the category icon on a
   wash of the category colour. It keeps the square: a shorter plate was
   quieter one-at-a-time, but the grid runs four across now and a row of
   three icons beside one photograph came out ragged, with the icon cards
   half empty at the foot. Matching the photo plate costs nothing and the
   rows line up. Drop is-icon in the markup when an <img> goes in. */
.pcard-plate.is-icon{
  background:color-mix(in srgb, var(--cat, var(--ink)) 7%, #fff);
}
.pcard-icon{
  width:clamp(38px,4.4vw,56px); height:auto; color:var(--cat, var(--muted));
  opacity:.8;
}
/* color-mix is well supported, but the fallback should still look designed
   rather than white-on-white if it is missing. */
@supports not (background: color-mix(in srgb, red 5%, #fff)){
  .pcard-plate.is-icon{background:var(--bg)}
}
.pcard-body{padding:clamp(11px,1.1vw,14px) clamp(12px,1.2vw,15px) 0}
/* Brand sits above the product name, so the grid reads brand-then-item at
   a glance without needing a second sort. Shop-wide lines carry no brand
   and the name simply moves up. */
.pcard-brand{
  font-size:.62rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--accent-deep); margin-bottom:5px;
}
.pcard-name{font-size:.88rem; font-weight:700; letter-spacing:-.014em; line-height:1.25; margin-bottom:4px}
.pcard-note{font-size:.73rem; line-height:1.45; color:var(--muted)}

/* ── the card as one control ─────────────────────────────────── */
/* The button is the product name; its ::after covers the card. One tab
   stop and one hit area per product, instead of a picture, a heading and
   a note that each look separately clickable. */
.pcard-open{
  font:inherit; color:inherit; text-align:start; background:none; border:0;
  padding:0; cursor:pointer;
}
.pcard-open::after{content:""; position:absolute; inset:0; z-index:2}
/* The outline belongs on the card, not on three words of it. */
.pcard-open:focus-visible{outline:none}
.pcard:has(.pcard-open:focus-visible){
  outline:2px solid var(--accent-deep); outline-offset:2px;
}
/* Nothing to open without script, or without <dialog>: the card goes back
   to being a card rather than offering a click that does nothing. */
html:not(.js) .pcard-open,
html.no-dialog .pcard-open{cursor:default}
html:not(.js) .pcard-open::after,
html.no-dialog .pcard-open::after{display:none}

/* ══ PRODUCT DIALOG ════════════════════════════════════════════════
   The card, opened. Same plate, same words, plus the two things the
   page can actually do for somebody: ring the shop, or get them to it.
   ══════════════════════════════════════════════════════════════════ */
.pdlg{
  width:min(100% - 2rem, 27rem); max-height:calc(100svh - 2rem);
  padding:0; border:0; border-radius:var(--radius); background:var(--panel);
  color:var(--ink); box-shadow:var(--shadow-lg); overflow:visible;
}
.pdlg::backdrop{background:rgba(15,18,21,.62)}
@supports (backdrop-filter: blur(2px)){
  .pdlg::backdrop{backdrop-filter:blur(3px)}
}
.pdlg-in{position:relative; display:flex; flex-direction:column; max-height:inherit}
/* Holds focus for the dialog without drawing a ring around the whole panel. */
.pdlg-in:focus{outline:none}
.pdlg-x{
  position:absolute; inset-block-start:10px; inset-inline-end:10px; z-index:3;
  display:grid; place-items:center; width:34px; height:34px; border-radius:50%;
  background:rgba(255,255,255,.86); color:var(--ink);
  box-shadow:var(--shadow-sm); backdrop-filter:blur(4px);
  transition:background-color .25s var(--ease), transform .25s var(--ease);
}
.pdlg-x svg{width:17px; height:17px}
.pdlg-x:hover{background:#fff; transform:scale(1.06)}

/* Same rules the grid plate uses, at dialog scale, so a packshot sits in
   the plate and a shelf photograph fills it exactly as it does on the card. */
.pdlg-plate{
  position:relative; aspect-ratio:4/3; display:grid; place-items:center;
  overflow:hidden; background:#fff;
  border-start-start-radius:var(--radius); border-start-end-radius:var(--radius);
}
.pdlg-plate picture{position:absolute; inset:0; display:grid; place-items:center}
/* Larger than the card's 84/76: seeing the thing properly is why the dialog
   opens at all. */
.pdlg-plate img{width:auto; height:auto; max-width:88%; max-height:90%; object-fit:contain}
.pdlg-plate.is-scene{background:var(--bg)}
.pdlg-plate.is-scene img{
  position:absolute; inset:0; width:100%; height:100%;
  max-width:none; max-height:none; object-fit:cover;
}
.pdlg-plate.is-icon{background:color-mix(in srgb, var(--cat, var(--ink)) 8%, #fff)}
.pdlg-plate .pcard-icon{width:clamp(56px,16vw,84px); height:auto; color:var(--cat, var(--muted)); opacity:.85}
.pdlg-plate::after{
  content:""; position:absolute; inset-inline:0; inset-block-end:0; height:3px;
  background:var(--cat, transparent); opacity:.9;
}

.pdlg-body{padding:clamp(18px,2.4vw,24px); overflow-y:auto}
.pdlg-brand{
  font-size:.68rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--accent-deep); margin-bottom:7px;
}
.pdlg-brand[hidden]{display:none}
.pdlg-name{font-size:1.3rem; font-weight:700; letter-spacing:-.022em; line-height:1.2}
.pdlg-note{margin-top:7px; font-size:.86rem; line-height:1.5; color:var(--muted)}
.pdlg-actions{display:flex; flex-direction:column; gap:10px; margin-top:clamp(18px,2.2vw,24px)}
.pdlg-actions .btn{justify-content:center; width:100%}

/* Reduced motion keeps it, just without the lift. */
@media (prefers-reduced-motion: no-preference){
  .pdlg[open]{animation:pdlgIn .28s var(--ease) both}
  @keyframes pdlgIn{from{opacity:0; transform:translateY(10px) scale(.985)}}
}

/* Category tints, so scrolling the page has some rhythm and a filtered
   view still looks like it belongs to a set. */
.pcard-plate::after{
  content:""; position:absolute; inset-inline:0; inset-block-end:0; height:2px;
  background:var(--cat, transparent); opacity:.85;
}
/* One colour per category. Deliberately a muted family rather than a
   rainbow: they tint the icon plate and draw the rule under it, so they have
   to sit quietly next to the ember accent. */
.cat-block[data-cat="disposables"] {--cat:#6F62C4}
.cat-block[data-cat="devices"]     {--cat:#4F6DAE}
.cat-block[data-cat="eliquid"]     {--cat:#2E8FA6}
.cat-block[data-cat="dab"]         {--cat:#3F7F6A}
.cat-block[data-cat="glass"]       {--cat:#2E7FA6}
.cat-block[data-cat="pipes"]       {--cat:#5E7A8C}
.cat-block[data-cat="hookah"]      {--cat:#8A6BA8}
.cat-block[data-cat="papers"]      {--cat:#C08A3E}
.cat-block[data-cat="wraps"]       {--cat:#A8703A}
.cat-block[data-cat="cigarettes"]  {--cat:#8C6E5A}
.cat-block[data-cat="cigars"]      {--cat:#A8552E}
.cat-block[data-cat="pouches"]     {--cat:#3F8C64}
.cat-block[data-cat="botanicals"]  {--cat:#5E9440}
.cat-block[data-cat="lighters"]    {--cat:#C4622A}
.cat-block[data-cat="gear"]        {--cat:#7C7468}
.cat-block[data-cat="sundries"]    {--cat:#6E757B}

.page-foot{
  margin-top:clamp(54px,7vw,96px); padding-top:clamp(34px,4vw,52px);
  border-top:1px solid var(--line); max-width:46rem;
}
.page-foot h2{margin-bottom:12px}
.page-foot p{color:var(--ink-2); font-size:.98rem; line-height:1.6; max-width:56ch}

/* Column counts are set against the width the GRID gets, not the viewport:
   past 1000px the sidebar takes 15.5rem out of it, and the page itself stops
   growing at 1240px. Four across is where the cards stop shrinking - the same
   density the shops themselves run, and a size the packshots can fill. */
@media (min-width:561px){ .pgrid{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media (min-width:801px){ .pgrid{grid-template-columns:repeat(4,minmax(0,1fr))} }
@media (min-width:1000px){ .pgrid{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media (min-width:1180px){ .pgrid{grid-template-columns:repeat(4,minmax(0,1fr))} }

/* ── the rail below the sidebar breakpoint ───────────────────── */
/* No room for a column, so the same control becomes a single scrolling row
   pinned under the header. Still one line, still always in reach, and the
   counts still ride along. */
@media (max-width:999px){
  .cat-side{
    position:sticky; inset-block-start:calc(var(--nav-h) - 1px); z-index:20;
    margin-inline:calc(var(--gutter) * -1); padding-inline:var(--gutter);
    padding-block:12px 11px; background:var(--bg);
    border-bottom:1px solid var(--line);
  }
  .cat-rail{
    flex-direction:row; gap:6px; margin-block-start:11px;
    overflow-x:auto; scrollbar-width:none;
    /* Bleed the row to the screen edges so the last chip is not trapped
       against the gutter, and pad it back so the first one is not either. */
    margin-inline:calc(var(--gutter) * -1); padding-inline:var(--gutter);
    scroll-padding-inline:var(--gutter);
  }
  .cat-rail::-webkit-scrollbar{display:none}
  .cat-chip{
    flex:0 0 auto; width:auto; border-radius:var(--pill);
    border-color:var(--line); background:var(--panel); padding:.5em .95em;
    font-size:.78rem; white-space:nowrap;
  }
  .cat-chip[aria-pressed="true"]{border-color:var(--ink)}
  .cat-chip-t{flex:0 0 auto}
  .cat-chip.is-here:not([aria-pressed="true"]) .cat-chip-t{box-shadow:none}
  /* products.html#glass has to clear the header AND the bar pinned under it,
     otherwise the deep link puts the heading behind the search field. */
  .cat-block{scroll-margin-top:calc(var(--nav-h) + 124px)}
}
@media (max-width:620px){
  .page-actions .btn{justify-content:center; width:100%}
  .cat-search input{font-size:16px}  /* iOS zooms anything smaller on focus */
}

/* ══════════════════════════════════════════════════════════════════
   LEAVE A REVIEW  ·  review.html only
   -------------------------------------------------------------------
   A fork with three states, on the graphite ground the visit block
   already uses. Dark page, one white card: the card is the only thing
   to look at, which is the point of a page with a single job.

   Steps are all in the markup and shown one at a time. Without script
   every step is visible in order, which reads as a slightly long page
   rather than a broken one - and the Google link and the phone number
   both still work, which is most of what this page is for.
   ══════════════════════════════════════════════════════════════════ */
.rv{
  position:relative; overflow:hidden;
  background:var(--ground); color:var(--on-dark);
  padding-block:calc(var(--nav-h) + clamp(30px,5vw,64px)) clamp(56px,8vw,104px);
  min-height:calc(100svh - var(--nav-h));
}
/* The same ember haze the hero uses, so the page belongs to the site
   rather than looking like a form somebody bolted on. */
.rv::before{
  content:""; position:absolute; inset-block-start:-30%; inset-inline-end:-18%;
  width:min(70vw,760px); aspect-ratio:1; border-radius:50%;
  background:radial-gradient(circle, rgba(242,112,63,.20), transparent 68%);
  pointer-events:none;
}
/* The page is one screen with one job, so the pair sits in the middle of it
   rather than at the top with the rest of the screen left over. */
.rv{display:grid; align-items:center}
.rv-in{position:relative; display:grid; gap:clamp(30px,4vw,64px); align-items:center}
@media (min-width:961px){
  .rv-in{grid-template-columns:minmax(0,1fr) minmax(0,26.5rem)}
}

/* ── the pitch ───────────────────────────────────────────────── */
.rv-copy{max-width:34rem}
.rv-copy .eyebrow{color:var(--accent)}
.rv-copy h1{margin:clamp(14px,2vw,20px) 0 clamp(14px,2vw,20px)}
.rv-copy .lead{color:var(--on-dark-2)}
.rv-chip{
  display:inline-flex; align-items:center; gap:.6em; margin-top:clamp(20px,2.6vw,28px);
  padding:.5em .95em; border:1px solid var(--line-dark); border-radius:var(--pill);
  font-size:.82rem; color:var(--on-dark-2); background:rgba(238,240,242,.04);
}
.rv-stars{display:inline-flex; gap:3px; color:var(--accent)}
.rv-stars span{
  width:13px; height:13px; background:currentColor;
  -webkit-mask:var(--star) center/contain no-repeat; mask:var(--star) center/contain no-repeat;
}
.rv-chip-t strong{color:var(--on-dark); font-weight:700}

/* ── the card ────────────────────────────────────────────────── */
.rv-funnel{
  background:var(--panel); color:var(--ink);
  border-radius:var(--radius); box-shadow:var(--shadow-lg);
  padding:clamp(22px,3vw,34px);
}
.rv-step{display:none}
.rv-step.is-active{display:block}
/* No script, no stepping: show the lot, separated so it still reads. */
html:not(.js) .rv-step{display:block}
html:not(.js) .rv-step + .rv-step{
  margin-top:clamp(26px,3.4vw,38px); padding-top:clamp(26px,3.4vw,38px);
  border-top:1px solid var(--line);
}
html:not(.js) .rv-backstep{display:none}

.rv-title{font-size:clamp(1.18rem,1.05rem + .5vw,1.42rem); font-weight:700; letter-spacing:-.022em; line-height:1.22}
.rv-note{margin-top:8px; font-size:.88rem; line-height:1.55; color:var(--muted)}
.rv-note a{color:var(--accent-deep)}

/* ── the fork ────────────────────────────────────────────────── */
.rv-choices{display:grid; gap:10px; margin-top:clamp(18px,2.4vw,24px)}
.rv-choice{
  display:flex; align-items:center; gap:14px; width:100%; text-align:start;
  padding:16px; border:1px solid var(--line); border-radius:11px;
  background:var(--panel); color:var(--ink); text-decoration:none; cursor:pointer;
  transition:border-color .3s var(--ease), background-color .3s var(--ease),
             transform .3s var(--ease), box-shadow .3s var(--ease);
}
.rv-choice:hover{transform:translateY(-2px); box-shadow:var(--shadow-sm)}
.rv-choice .ar{margin-inline-start:auto; flex:0 0 auto; opacity:.5}
.rv-choice:hover .ar{opacity:1}
.rv-choice-ic{
  flex:0 0 auto; display:grid; place-items:center; width:42px; height:42px;
  border-radius:11px;
}
.rv-choice-ic svg{width:21px; height:21px}
.rv-choice-t{display:flex; flex-direction:column; gap:3px; min-width:0}
.rv-choice-h{font-size:.95rem; font-weight:700; letter-spacing:-.014em}
.rv-choice-d{font-size:.78rem; line-height:1.4; color:var(--muted)}

/* The happy path is the filled one. Not to hide the other - it is the
   same size, directly under it, and says what it does - but because it
   is what most people came to do. */
.rv-choice.is-good{border-color:var(--accent-deep); background:color-mix(in srgb, var(--accent-deep) 5%, #fff)}
.rv-choice.is-good:hover{background:color-mix(in srgb, var(--accent-deep) 9%, #fff)}
.rv-choice.is-good .rv-choice-ic{background:var(--accent-deep); color:#fff}
.rv-choice.is-bad:hover{border-color:rgba(23,25,28,.3); background:var(--bg)}
.rv-choice.is-bad .rv-choice-ic{background:var(--bg); color:var(--ink-2); border:1px solid var(--line)}
@supports not (background: color-mix(in srgb, red 5%, #fff)){
  .rv-choice.is-good{background:var(--bg)}
}

/* ── the private form ────────────────────────────────────────── */
.rv-fields{display:grid; gap:14px; margin-top:clamp(18px,2.4vw,24px)}
@media (min-width:520px){
  .rv-fields{grid-template-columns:1fr 1fr}
  .rv-field.is-wide{grid-column:1 / -1}
}
.rv-field{display:flex; flex-direction:column; gap:6px; min-width:0}
.rv-field label{
  font-size:.68rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-2);
}
.rv-opt{font-weight:500; letter-spacing:.06em; text-transform:none; color:var(--muted)}
.rv-field input,.rv-field textarea{
  font:inherit; font-size:16px;   /* 16px or iOS zooms the page on focus */
  color:var(--ink); background:var(--panel);
  border:1px solid var(--line); border-radius:9px; padding:.68em .8em;
  transition:border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.rv-field textarea{resize:vertical; min-height:104px; line-height:1.5}
.rv-field input:focus,.rv-field textarea:focus{
  outline:none; border-color:var(--ink); box-shadow:var(--shadow-sm);
}
/* Off-screen rather than display:none: a bot reading the markup fills it,
   and hidden fields are the first thing they skip. */
.rv-hp{position:absolute; left:-9999px; width:1px; height:1px; opacity:0}

.rv-submit{width:100%; justify-content:center; margin-top:clamp(18px,2.2vw,22px)}
.rv-status{margin-top:12px; font-size:.84rem; line-height:1.5; color:var(--accent-deep)}
.rv-status:empty{display:none}
.rv-fine{margin-top:14px; font-size:.76rem; line-height:1.5; color:var(--muted)}
.rv-fine a{color:var(--accent-deep)}
.rv-backstep{
  margin-top:16px; font-size:.78rem; font-weight:600; color:var(--muted);
  background:none; border:0; padding:0; cursor:pointer;
}
.rv-backstep::before{content:"\2190\00a0"}
.rv-backstep:hover{color:var(--ink)}

/* ── done ────────────────────────────────────────────────────── */
.rv-done{text-align:center; padding-block:clamp(10px,2vw,20px)}
.rv-tick{
  display:grid; place-items:center; width:56px; height:56px; margin:0 auto 18px;
  border-radius:50%; background:color-mix(in srgb, var(--accent-deep) 10%, #fff);
  color:var(--accent-deep);
}
.rv-tick svg{width:26px; height:26px}
.rv-done .rv-note{margin-inline:auto; max-width:34ch}
.rv-done-act{margin-top:clamp(20px,2.6vw,26px)}

/* ── the stripped header ─────────────────────────────────────── */
/* Same bar as everywhere else; the nav, the call button and the burger
   simply are not in the markup on this page. */
.rv-back{
  display:inline-flex; align-items:center; gap:.5em; margin-inline-start:auto;
  font-size:.8rem; font-weight:600; letter-spacing:.02em;
  color:var(--on-dark-2); text-decoration:none;
  transition:color .3s var(--ease);
}
.rv-back:hover{color:var(--on-dark)}
.hdr-bare .hdr-in{gap:16px}

@media (max-width:620px){
  .rv-funnel{padding:20px 16px}
  .rv-choice{padding:14px}
}

/* Leave a Review sits in the nav in ember, so it reads as the one ask in a
   bar of destinations. Same rule and hover as its neighbours. */
.nav a.nav-rv{color:var(--accent)}
.nav a.nav-rv:hover{color:var(--accent-deep)}
.drawer a.nav-rv{color:var(--accent)}

/* The fork card carries less than the form step does, so it gets its own
   width and breathing room rather than sitting small beside the headline. */
@media (min-width:961px){
  .rv-in{grid-template-columns:minmax(0,1fr) minmax(0,31rem)}
}
.rv-funnel{padding:clamp(26px,3.6vw,42px)}
#step-ask .rv-title{font-size:clamp(1.35rem,1.15rem + .7vw,1.7rem)}
#step-ask .rv-note{font-size:.95rem}
#step-ask .rv-choices{gap:14px}
#step-ask .rv-choice{padding:22px}
#step-ask .rv-choice-ic{width:52px; height:52px; border-radius:13px}
#step-ask .rv-choice-ic svg{width:25px; height:25px}
#step-ask .rv-choice-h{font-size:1.05rem}
#step-ask .rv-choice-d{font-size:.85rem}

/* ── review page background ──────────────────────────────────── */
.rv-bg{position:absolute; inset:0; z-index:0; overflow:hidden}
.rv-bg img{width:100%; height:100%; object-fit:cover; object-position:center}
/* Two scrims: a flat one so text contrast holds anywhere, and a gradient
   that keeps the left column - where the headline sits - darkest. */
.rv-bg::after{
  content:""; position:absolute; inset:0;
  background:
    linear-gradient(90deg, rgba(22,25,28,.94) 0%, rgba(22,25,28,.86) 45%, rgba(22,25,28,.72) 100%),
    rgba(22,25,28,.34);
}
.rv-in{z-index:1}

/* Real logos now, not name slots: three across so six fill two clean rows.
   Every mark is one ink silhouette at a matched cap height, so the strip
   reads as a set rather than as nine different house styles. */
@media (min-width:901px){ .brand-grid{grid-template-columns:repeat(3,1fr)} }
@media (max-width:620px){ .brand-grid{grid-template-columns:repeat(2,1fr)} }
.brand-cell{min-height:120px}
.brand-logo{
  /* Height-led, so a portrait mark like Zig-Zag is not left a
     postage stamp beside a wide one like ZYN. */
  width:auto; height:auto; max-width:70%; max-height:62px; object-fit:contain;
  opacity:.62; transition:opacity .35s var(--ease);
}
.brand-cell:hover .brand-logo{opacity:1}
