/* Double Shot Marketing — component layer. Depends on tokens.css + base.css. */

/* ---------- nav ---------- */
.nav-bar{background:var(--ink);position:sticky;top:0;z-index:40;}
.nav-bar .nav-links a:not(.btn){color:var(--paper);}
.nav-bar .nav-links a:not(.btn):hover{color:var(--orange-bleach);}

/* transparent poster header: no color separation from the page (site hero) */
.nav-clear{background:transparent;position:static;}
/* Marshall's pick 2026-08-04: cups mark + stacked lockup, both 78px, in a 100px bar.
   The bar is sized to the logo rather than the logo floating inside a fixed bar: the
   stacked SVG has only 1.6% slack of its own, so nav height was the only real lever. */
.nav-clear .nav{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;height:100px;}
.nav-clear .nav-logo{justify-self:start;gap:17px;}
.nav-clear .nav-logo img{height:78px;}
/* Marshall's call 2026-08-04: no pill, ink type straight on the orange.
   Note this is the one place the contrast law is knowingly bent: ink on orange is 4.14:1,
   which clears AA for large text (3:1) but not for normal text (4.5:1). Sized at 14px the
   tabs sit just under that line. Raising them to 19px/500 would clear it outright. */
.nav-tabs{justify-self:center;display:flex;gap:34px;align-items:center;background:none;padding:0;}
.nav-tabs a{font-family:var(--font-mono);font-weight:500;font-size:14px;letter-spacing:.24em;text-transform:uppercase;color:var(--ink);transition:color var(--dur-hover) var(--ease-out);}
.nav-tabs a:hover{color:var(--orange-deep);}
.nav-tabs a:active{opacity:.6;}
.nav-tabs a:focus-visible{outline:3px solid var(--ink);outline-offset:4px;border-radius:2px;}
.nav-clear .nav-cta{justify-self:end;}
@media (max-width:860px){
  .nav-clear .nav{height:74px;grid-template-columns:auto 1fr;gap:10px;}
  .nav-clear .nav-logo{gap:9px;}
  .nav-clear .nav-logo img{height:46px;}
  .nav-tabs{justify-self:end;gap:11px;padding:0;}
  .nav-tabs a{font-size:9.5px;letter-spacing:.08em;}
  .nav-clear .nav-cta{display:none;}
}
/* Small phones: logo 140px + tabs 188px overran a 280px usable width and put the whole
   document into horizontal scroll. Four tabs is the constraint, so both sides give. */
@media (max-width:400px){
  .nav-clear .nav-logo{gap:7px;}
  .nav-clear .nav-logo img{height:32px;}
  .nav-tabs{gap:8px;}
  .nav-tabs a{font-size:9px;letter-spacing:.04em;}
}
.nav{display:flex;align-items:center;justify-content:space-between;height:72px;}
.nav-logo{display:flex;align-items:center;}
.nav-logo img{height:36px;display:block;}
.nav-links{display:flex;gap:30px;align-items:center;}
.nav-links a:not(.btn){font-family:var(--font-mono);font-weight:500;font-size:13.5px;letter-spacing:.28em;text-transform:uppercase;position:relative;padding:4px 0;}
.nav-links a:not(.btn):hover{color:var(--orange-deep);}
.nav-links a:not(.btn):active{opacity:.6;}
.nav-links .btn{padding:11px 22px;font-size:15px;}
@media (max-width:860px){
  .nav{height:64px;}
  .nav-logo img{height:27px;}
  .nav-links{gap:14px;}
  .nav-links a:not(.btn){font-size:11px;letter-spacing:.2em;}
  .nav-links .btn{padding:9px 14px;font-size:12.5px;}
}

/* ---------- hero ---------- */
/* The cup must cover only the BOTTOM HALF of the K, in every placement (Marshall,
   2026-08-06). That is a relationship to the headline, not to the bottom of the
   hero, so the cup is positioned from the TOP off the headline's own font size.
   0.3842 is where the WAKE line's cap-height midpoint falls, measured in real
   pixels (tools/measure-k-overlap.py), and it holds at every size because the
   ink scales with the font. 0.0247 subtracts the transparent padding above the
   art inside the PNG (30px of 1536, on a 1214/1536 canvas).
   Change the art's aspect or its top padding and these two numbers move. */
.hero{padding:20px 0 90px;position:relative;overflow:hidden;min-height:calc(100dvh - 100px);display:flex;align-items:flex-start;
  --wake-fs:clamp(170px, 24.5vw, 355px);
  --cup-w:clamp(340px, 39vw, 570px);
  --cup-top:calc(var(--wake-fs) * 0.3842 - var(--cup-w) * 0.0247);}
.hero-stage{position:relative;width:100%;}
.hero-wake{font-family:'Archivo Black',var(--font-display);font-weight:400;color:var(--ink);line-height:.8;letter-spacing:-.015em;position:relative;z-index:1;}
.hero-wake .l{display:block;font-size:var(--wake-fs);}
.hero-cup{position:absolute;z-index:2;left:46%;top:var(--cup-top);bottom:auto;width:var(--cup-w);pointer-events:none;
  filter:drop-shadow(10px 14px 0 rgba(41,35,31,.25));
  -webkit-mask-image:linear-gradient(to bottom, #000 80%, transparent 99%);
  mask-image:linear-gradient(to bottom, #000 80%, transparent 99%);
  /* Ambient sway: transform-only so it stays on the compositor, pivot at the wrist.
     Max drift is 3px vertical / 0.5deg, inside the half-K rule's own 2px tolerance band
     at the static pose the sweep measures (render.mjs --reduced kills all of this). */
  transform-origin:62% 96%;will-change:transform;
  animation:cup-sway 9.5s ease-in-out infinite;}
@keyframes cup-sway{
  0%,100%{transform:rotate(0deg) translateY(0)}
  28%{transform:rotate(.5deg) translateY(-2px)}
  54%{transform:rotate(-.25deg) translateY(-3px)}
  78%{transform:rotate(.3deg) translateY(-1px)}
}
/* Steam anchors to the cup's own vars: rim centre sits at 38.6% of the art's width
   (measured from the PNG's alpha), so a --cup-w change or the mobile left override
   re-aims it for free. transform + opacity only. */
.hero-steam{position:absolute;z-index:2;pointer-events:none;
  left:calc(46% + var(--cup-w) * 0.386);
  top:calc(var(--cup-top) - var(--cup-w) * 0.335);
  width:calc(var(--cup-w) * 0.30);
  height:calc(var(--cup-w) * 0.425);
  transform:translateX(-50%);}
/* Paper, not ink: the rim sits under the K's ink at desktop, and ink-on-ink steam
   vanishes for most of its rise. Paper reads on both grounds and is the cup's own fill.
   Wisps are FILLED tapered brush ribbons (Marshall killed the stroked version as "too
   HTML"); the .5px blur softens the vector edge so they read as vapor, not shapes. */
.hero-steam path{fill:var(--paper);filter:blur(.5px);
  transform-box:fill-box;transform-origin:center;
  animation:steam-waver var(--wav,3.4s) ease-in-out infinite alternate;}
.hero-steam .wisp{opacity:0;transform-box:fill-box;transform-origin:50% 100%;
  will-change:transform,opacity;
  animation:steam-rise var(--dur,6s) linear infinite;animation-delay:var(--del,0s);}
.hero-steam .w1{--dur:5.7s;--del:-1.2s;--drift:7px;--wav:3.1s}
.hero-steam .w2{--dur:6.9s;--del:-4.1s;--drift:-6px;--wav:3.9s}
.hero-steam .w3{--dur:7.9s;--del:-2.7s;--drift:9px;--wav:3.5s}
@keyframes steam-rise{
  0%{transform:translate(0,14px) scale(.82);opacity:0}
  12%{opacity:.5}
  55%{opacity:.32}
  100%{transform:translate(var(--drift),-96px) scale(1.1);opacity:0}
}
@keyframes steam-waver{
  from{transform:translateX(-2.5px)}
  to{transform:translateX(2.5px)}
}
@media (prefers-reduced-motion:reduce){
  .hero-cup{animation:none}
  .hero-steam{display:none}
}
.hero-foot{position:relative;z-index:3;margin-top:44px;max-width:46ch;}
.hero-sub{font-size:22px;font-weight:700;line-height:1.5;color:var(--ink);max-width:42ch;}
.hero-ctas{margin-top:32px;display:flex;gap:16px;flex-wrap:wrap;}
/* One mobile block, not two. The old second block silently re-set .hero padding and
   .hero-sub size, and carried rules for .hero-grid and .hero-poster, which no longer
   exist in the markup. */
@media (max-width:860px){
  /* Only the two inputs change here. --cup-top and the K rule come from the
     shared block above, so mobile lands on the same half-K overlap as desktop. */
  .hero{padding:8px 0 64px;min-height:auto;--cup-w:min(58vw,300px);--wake-fs:clamp(88px, 24vw, 135px);}
  /* The cup is absolutely positioned, so it used to sit on top of the sub paragraph and
     swallow words. Reserving the cup's own height on the headline block pushes the foot
     clear of it in flow, at every width, instead of guessing a margin. 1.264 is the
     cup asset's height/width ratio; --cup-top is added because the cup now starts
     below the headline's top, not at it. */
  .hero-cup{left:44%;}
  .hero-steam{left:calc(44% + var(--cup-w) * 0.386);}
  .hero-wake{min-height:calc(var(--cup-w) * 1.264 + var(--cup-top));}
  .hero-foot{margin-top:24px;max-width:none;}
  .hero-sub{font-size:18px;max-width:32ch;}
}

/* ---------- section shells ---------- */
.section{padding:var(--space-section) 0;}
.section-shaded{background:var(--paper-deep);border-top:var(--frame);border-bottom:var(--frame);}
.section-ink{background:var(--ink);color:var(--paper);}
.section-cream{background:var(--paper);border-top:var(--frame);border-bottom:var(--frame);}
.section h2{font-size:52px;}
.section .lead{margin-top:14px;font-size:20px;font-weight:700;color:var(--ink);max-width:52ch;}
.section-cream .lead{color:var(--ink-soft);font-weight:400;}
@media (max-width:860px){
  .section{padding:var(--space-section-m) 0;}
  .section h2{font-size:36px;}
}

/* ---------- menu board (signature) ---------- */
.menu-board{
  margin-top:52px;background:var(--ink);color:var(--paper);border-radius:var(--radius-container);
  padding:44px 52px 36px;box-shadow:var(--block-shadow-roast);
}
.menu-board .mb-title{font-family:var(--font-mono);font-weight:500;font-size:16px;letter-spacing:.3em;margin-bottom:18px;}
.mrow{display:grid;grid-template-columns:250px 1fr auto;align-items:baseline;column-gap:28px;
  border-bottom:1.5px solid var(--hairline-on-ink);padding:20px 0;}
.mrow:last-child{border-bottom:none;}
.mname{font-weight:700;font-size:24px;white-space:nowrap;}
.mdesc{font-size:17px;color:var(--paper-75);}
.mprice{font-family:var(--font-mono);font-size:17px;color:var(--orange-bleach);white-space:nowrap;}
@media (max-width:860px){
  .menu-board{padding:28px 24px 20px;}
  .mrow{grid-template-columns:1fr auto;row-gap:6px;padding:16px 0;}
  .mname{font-size:20px;white-space:normal;}
  .mdesc{grid-column:1 / -1;font-size:15.5px;}
  .mprice{font-size:15px;}
}
/* ---------- menu board, list variant (no prices) ----------
   Marshall's call 2026-08-05: publish the full range of services, not the rates. Same
   backlit board, but the rows become categorised lists so every service someone might
   search for is actually on the page. The bean is the bullet, which is a role DESIGN.md
   already assigns it. */
.menu-board .mgrid{display:grid;grid-template-columns:1fr 1fr;gap:0 60px;}
.msec{border-top:1.5px solid var(--hairline-on-ink);padding:26px 0 10px;}
.msec-h{font-weight:700;font-size:22px;color:var(--paper);margin-bottom:15px;}
.mitem{display:flex;align-items:flex-start;gap:11px;font-size:16.5px;line-height:1.45;
  color:var(--paper-75);padding:6px 0;}
.mitem .bean{height:13px;flex-shrink:0;margin-top:5px;}
@media (max-width:860px){
  .menu-board .mgrid{grid-template-columns:1fr;gap:0;}
  .msec{padding:22px 0 8px;}
  .msec-h{font-size:19px;}
  .mitem{font-size:15.5px;}
}
/* the one authored motion moment: the board lights on like a backlit lightbox,
   now with a one-time fluorescent-tube warm-up flicker (two dips, then steady).
   Under reduced motion the global animation kill leaves the smooth transition. */
.menu-board.lightbox{opacity:.4;filter:brightness(.55);transition:opacity .6s var(--ease-out),filter .8s var(--ease-out);}
.menu-board.lightbox .mrow,.menu-board.lightbox .msec{opacity:0;transform:translateY(10px);transition:opacity .45s var(--ease-out),transform .45s var(--ease-out);}
.menu-board.lightbox.is-lit{opacity:1;filter:brightness(1);animation:board-warmup .95s ease-out;}
@keyframes board-warmup{
  0%{opacity:.4;filter:brightness(.55)}
  9%{opacity:1;filter:brightness(1.05)}
  15%{opacity:.5;filter:brightness(.58)}
  25%{opacity:1;filter:brightness(1.07)}
  33%{opacity:.78;filter:brightness(.84)}
  45%{opacity:1;filter:brightness(1.02)}
  100%{opacity:1;filter:brightness(1)}
}
.menu-board.lightbox.is-lit .mrow,.menu-board.lightbox.is-lit .msec{opacity:1;transform:none;}
.menu-board.lightbox.is-lit .msec:nth-child(2){transition-delay:.10s}
.menu-board.lightbox.is-lit .msec:nth-child(3){transition-delay:.20s}
.menu-board.lightbox.is-lit .msec:nth-child(4){transition-delay:.30s}
.menu-board.lightbox.is-lit .mrow:nth-child(2){transition-delay:.08s}
.menu-board.lightbox.is-lit .mrow:nth-child(3){transition-delay:.16s}
.menu-board.lightbox.is-lit .mrow:nth-child(4){transition-delay:.24s}
.menu-board.lightbox.is-lit .mrow:nth-child(5){transition-delay:.32s}
.menu-board.lightbox.is-lit .mrow:nth-child(6){transition-delay:.40s}
.menu-board.lightbox.is-lit .mrow:nth-child(7){transition-delay:.48s}
@media (prefers-reduced-motion: reduce){
  .menu-board.lightbox{opacity:1;filter:none;transition:none;}
  .menu-board.lightbox .mrow,.menu-board.lightbox .msec{opacity:1;transform:none;transition:none;}
}

/* ---------- promise ledger ---------- */
.promises{margin-top:64px;display:grid;grid-template-columns:290px 1fr;}
.promise{display:contents;}
.promise .p-name{font-family:var(--font-mono);font-weight:500;font-size:16px;letter-spacing:.26em;color:var(--orange-bleach);border-top:1.5px solid var(--hairline-on-ink);padding:30px 0;white-space:nowrap;}
.promise .p-body{font-size:19px;color:rgba(242,235,223,.82);border-top:1.5px solid var(--hairline-on-ink);padding:28px 0 28px 40px;}
@media (max-width:860px){
  .promises{grid-template-columns:1fr;margin-top:44px;}
  .promise .p-name{padding:22px 0 4px;}
  .promise .p-body{border-top:none;padding:0 0 22px;}
}

/* ---------- founders ---------- */
.founders{display:grid;grid-template-columns:1fr 1fr;gap:60px;}
/* Die-cut portraits in the print-sticker register: hard offset shadow (the cup's own
   idiom), bottom fade mask (the hero cup's own device, so the waist-line cut never
   shows), ring stain behind at <=50% opacity per the element job table. */
.founder .f-photo{position:relative;height:300px;margin-bottom:26px;}
.founder .f-photo img{position:absolute;left:6px;bottom:0;height:100%;width:auto;
  filter:drop-shadow(12px 14px 0 rgba(41,35,31,.18));
  -webkit-mask-image:linear-gradient(to bottom,#000 82%,transparent 100%);
  mask-image:linear-gradient(to bottom,#000 82%,transparent 100%);}
@media (max-width:860px){.founder .f-photo{height:250px;}}
.founder .f-name{font-weight:800;font-size:32px;line-height:1.05;letter-spacing:var(--track-tight);}
.founder .f-meta{font-family:var(--font-mono);font-weight:500;font-size:12.5px;letter-spacing:.22em;
  color:var(--orange-deep);margin-top:9px;}
.founder p{margin-top:18px;font-size:17.5px;line-height:1.62;color:var(--ink-soft);max-width:44ch;}
@media (max-width:860px){
  .founders{grid-template-columns:1fr;gap:40px;}
  .founder .f-name{font-size:27px;}
}

/* ---------- photo frame ---------- */
.photo-frame{
  border-radius:var(--radius-container);border:var(--frame);overflow:hidden;
  box-shadow:var(--block-shadow);background:var(--paper-deep);
}
.photo-frame img{width:100%;height:100%;object-fit:cover;display:block;filter:saturate(.86) contrast(.97);}

/* ---------- pull quote ---------- */
.pull-quote blockquote{font-weight:700;font-size:36px;line-height:1.3;letter-spacing:-.01em;max-width:26ch;margin:0 auto;text-align:center;}
.pull-quote .attr{margin-top:30px;text-align:center;font-family:var(--font-mono);font-size:15px;color:var(--ink-soft);}
@media (max-width:860px){.pull-quote blockquote{font-size:26px;}}

/* ---------- CTA field ---------- */
.cta-field{
  border-radius:var(--radius-container);padding:88px 64px;color:var(--paper);
  display:flex;flex-direction:column;align-items:flex-start;
  box-shadow:8px 10px 0 var(--shadow-roast);
}
.cta-field h2{font-family:var(--font-display);font-weight:400;font-size:64px;line-height:.98;color:var(--paper);}
.cta-field .body{margin-top:22px;font-size:20px;line-height:1.55;max-width:44ch;font-weight:500;color:rgba(242,235,223,.85);}
.cta-field .btn{margin-top:38px;font-size:18px;padding:17px 36px;}
@media (max-width:860px){
  .cta-field{padding:52px 28px;}
  .cta-field h2{font-size:38px;}
}

/* ---------- footer ---------- */
.footer{background:var(--ink);color:var(--paper);padding:64px 0 40px;}
.foot-grid{display:flex;justify-content:space-between;align-items:flex-start;gap:40px;}
.foot-logo{font-family:var(--font-display);font-size:24px;display:flex;align-items:center;}
.foot-logo .bean{height:17px;margin:0 2px;}
.foot-contact{font-family:var(--font-mono);font-size:14.5px;line-height:2;text-align:right;}
.foot-contact a:hover{color:var(--orange-bleach);}
.foot-contact a:active{opacity:.6;}
/* Bean conveyor: two identical belts drift left forever; each belt is exactly one
   loop, so -100% of its own width lands on the seam invisibly. Linear = roaster line. */
.foot-beans{margin-top:48px;display:flex;align-items:center;border-top:1.5px solid var(--hairline-on-ink);padding-top:28px;overflow:hidden;}
.foot-beans .belt{flex:none;display:flex;align-items:center;gap:88px;padding-right:88px;width:max-content;animation:belt-drift 34s linear infinite;}
@media (max-width:700px){.foot-beans .belt{gap:44px;padding-right:44px;animation-duration:26s;}}
.foot-beans .bean{height:20px;}
@keyframes belt-drift{to{transform:translateX(-100%)}}
@media (prefers-reduced-motion:reduce){.foot-beans{justify-content:space-between;}}

/* ---------- cup gauge (scroll progress) ---------- */
.cup-gauge{position:fixed;right:22px;bottom:22px;z-index:60;width:54px;height:54px;
  border-radius:50%;background:var(--paper);border:2.5px solid var(--ink);
  display:grid;place-items:center;cursor:pointer;padding:0;
  box-shadow:6px 8px 0 rgba(41,35,31,.22);
  transition:transform 160ms var(--ease-out);}
.cup-gauge:active{transform:scale(.94);}
.cup-gauge svg{width:32px;height:32px;overflow:visible;}
.cup-gauge .gauge-body,.cup-gauge .gauge-steam{fill:none;stroke:var(--ink);stroke-width:1.7;stroke-linecap:round;}
.cup-gauge .gauge-fill{fill:var(--orange-roast);transform:translateY(11.5px);}
.cup-gauge .gauge-steam{opacity:0;}
.cup-gauge.is-full .gauge-steam{animation:gauge-steam 2.2s ease-in-out infinite;}
.cup-gauge.is-full .gauge-steam.s2{animation-delay:-1.1s;}
@keyframes gauge-steam{
  0%{opacity:0;transform:translateY(1.6px)}
  30%{opacity:.85}
  100%{opacity:0;transform:translateY(-1.8px)}
}
@media (max-width:700px){.cup-gauge{width:46px;height:46px;right:14px;bottom:14px;}
  .cup-gauge svg{width:27px;height:27px;}}
@media (prefers-reduced-motion:reduce){.cup-gauge.is-full .gauge-steam{opacity:.85;}}
.foot-line{margin-top:30px;display:flex;justify-content:space-between;font-family:var(--font-mono);font-size:12px;letter-spacing:.12em;color:var(--paper-60);}
@media (max-width:860px){
  .foot-grid{flex-direction:column;}
  .foot-contact{text-align:left;}
  .foot-line{flex-direction:column;gap:8px;}
}

/* ---------- style-guide furniture (styleguide.html only) ---------- */
.sg-plate{border:var(--frame);border-radius:0;background:var(--paper);margin-top:40px;}
.sg-head{display:flex;justify-content:space-between;align-items:center;padding:10px 16px;border-bottom:var(--frame);font-family:var(--font-mono);font-size:12px;letter-spacing:.14em;}
.sg-body{padding:34px;}
.sg-grid{display:grid;gap:22px;}
.sg-swatch{display:flex;align-items:center;justify-content:space-between;padding:18px;font-family:var(--font-mono);font-size:13.5px;border-radius:8px;}
.sg-note{font-family:var(--font-mono);font-size:12.5px;color:var(--ink-soft);line-height:1.7;max-width:70ch;}
.sg-do{color:var(--ink);font-weight:700;}
.sg-specimen{border-top:1.5px solid var(--ink);padding-top:14px;margin-top:18px;display:flex;align-items:baseline;justify-content:space-between;gap:16px;}
.sg-label{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.1em;color:var(--ink-soft);white-space:nowrap;}
@media (max-width:860px){.sg-body{padding:20px;}}
