@import url("fonts.css");

/* ==========================================================================
   Cocktails Your Way — Design System
   Built from DS-Moderation-Branding-Guide-2026 + Aaron's landing page comp.
   Type ratios are the brand guide's, expressed as calc() off one display size
   so the relationship survives every breakpoint.
   ========================================================================== */

:root {
  /* --- Palette: Espresso Martini (evergreen default) --- */
  --cream:        #FFFCE6;
  --cream-warm:   #FEFADF;
  --offwhite:     #F6F6F6;
  --tan:          #DEB98F;
  --brown:        #572200;
  --brown-deep:   #4E1F0F;
  --brown-shadow: #431300;

  /* --- Palette: Cosmopolitan --- */
  --red:          #E64622;
  --red-mid:      #910200;
  --maroon:       #530201;

  /* --- Palette: Mojito --- */
  --yellow:       #FEDD04;
  --olive:        #607725;
  --olive-deep:   #4D4204;

  /* --- Accents --- */
  --orange:       #FF7802;
  --amber:        #CB8A0C;

  /* --- Semantic --- */
  --bg:           var(--cream);
  --ink:          var(--brown);
  --rule:         color-mix(in srgb, var(--brown) 22%, transparent);

  /* --- Type families ---------------------------------------------------
     The three licensed faces are declared first. Drop the real .woff2 into
     assets/fonts/ and add the @font-face in fonts-brand.css; until then the
     browser falls through to the closest free stand-in automatically.      */
  /* First name in each stack is the licensed face from the Adobe Fonts kit,
     spelled exactly as the kit declares it — "pd-monolina-brush", not
     "PD Monolina Brush". Family matching is case-insensitive but not
     punctuation-insensitive, so the human-readable spelling silently never
     matches and the script quietly stays on Permanent Marker.
     The stand-ins stay behind them: pull the kit ID and the site still runs. */
  --font-display: "veneer", "Bebas Neue", "Oswald", Impact, sans-serif;
  --font-header:  "neuzon", "Archivo Black", "Arial Black", sans-serif;
  --font-script:  "pd-monolina-brush", "Permanent Marker", cursive;
  --font-body:    "Raleway", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* --- Type scale (brand guide ratios) ---------------------------------
     display  = D            leading 0.80   ALWAYS CAPS
     callout  = 0.4  x D     leading 0.85   ALWAYS CAPS
     header   = 0.20 x D     leading 0.75   ALWAYS CAPS
     body     < header       leading 1.50                                  */
  /* Measured from the comp: "ALL THE" has a 182pt cap height on a 1920pt
     artboard (9.5vw). Veneer's cap/em works out at 0.728 and Anton's at
     0.714, so the same 13vw font-size lands within 2% either way — the
     licensed font can drop in without re-tuning this. */
  --display:  clamp(3.25rem, 13vw, 13rem);
  --callout:  calc(var(--display) * 0.4);
  --header:   calc(var(--display) * 0.2);
  --body:     clamp(1rem, 1.15vw, 1.375rem);

  /* The guide's ratios, and they hold now that the display size is right:
     250pt type on 200pt leading = 0.80. Header is 0.75. */
  --display-leading: .80;
  --header-leading:  .75;   /* guide value; was .78 for Archivo Black's taller caps */

  /* --- Rhythm --- */
  --section-pad: clamp(4.5rem, 9vw, 9rem);
  --gutter:      clamp(1.25rem, 4vw, 4.5rem);
  --content-max: 1320px;
  --measure:     68ch;

  /* --- Motion --- */
  --ease-expo:  cubic-bezier(.16, 1, .3, 1);
  --ease-out:   cubic-bezier(.22, .61, .36, 1);
  --speed:      1;                    /* scaled per-block from ACF */
  --reveal-dur: calc(0.95s * var(--speed));

  /* --- Texture intensity (set to 0 once real distressed faces land) --- */
  --distress: 0.55;
  --erode: url("../img/textures/erode.png");   /* set to none by the options block at 0 */
  --grain:    0.07;
}

/* ==========================================================================
   Base
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--body);
  line-height: 1.5;
  /* clip, not hidden — `hidden` makes body a scroll container and silently
     breaks position:sticky on the nav. */
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

img, svg, video { display: block; max-width: 100%; }
a { color: inherit; }

:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 3px;
  border-radius: 2px;
}

.screen-reader-text {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

.skip-link {
  position: absolute; left: 50%; top: 0;
  transform: translate(-50%, -120%);
  z-index: 999;
  background: var(--brown); color: var(--cream);
  padding: .75rem 1.25rem; font-family: var(--font-header);
  text-decoration: none; transition: transform .2s;
}
.skip-link:focus { transform: translate(-50%, 0); }

/* ==========================================================================
   Type primitives
   ========================================================================== */

.t-display, .t-callout, .t-header {
  text-transform: uppercase;
  margin: 0;
  font-weight: 400;
}

/* The brand's leading is tighter than the glyphs (0.8 / 0.75), so each block
   gets a little padding to stop ascenders and descenders colliding with the
   element above and below. */
.t-display {
  font-family: var(--font-display);
  font-size: var(--display);
  line-height: var(--display-leading);
  letter-spacing: .005em;
  padding-block: .04em;
}

.t-callout {
  font-family: var(--font-display);
  font-size: var(--callout);
  line-height: .85;
  padding-block: .05em;
}

.t-header {
  font-family: var(--font-header);
  font-size: var(--header);
  line-height: var(--header-leading);
  letter-spacing: .01em;
  padding-block: .08em;
}

/* Multi-line display copy: one .display-line per line so the client controls
   exactly where "ALL THE / FLAVOR" breaks, as in the comp. */
.display-line { display: block; }

.t-script {
  font-family: var(--font-script);
  text-transform: none;
  font-weight: 400;
}

/* Form controls do not inherit font-family — the UA stylesheet hands them the
   system font instead. Without this the builder's eight recipe tiles, its
   steppers, its amount fields and the nav toggle all render in Arial, which is
   easy to miss because the surrounding copy is correct. font-family only, not
   `font: inherit`: the sizes are already set deliberately per component. */
button, input, select, textarea, optgroup {
  font-family: inherit;
}

.t-body {
  font-family: var(--font-body);
  font-size: var(--body);
  line-height: 1.5;
  max-width: var(--measure);
  margin-inline: auto;
}

/* Letterpress erosion — stands in for Veneer/Neuzon's built-in distress.
   Masking (not opacity) so the holes read as ink that never hit the paper.

   Kept deliberately fine-grained: a large tile eats whole chunks out of the
   letterforms and is expensive for the compositor to rasterise over display
   type this size. --distress (Campaign → Motion) scales it; 0 turns it off,
   which is what you want once the real Veneer/Neuzon faces are installed. */
.is-distressed {
  /* The mask image comes through a variable so it can be switched off from the
     options <style> block in the head. It used to be turned off with
     :root[style*="--distress:0.000"], which could never match: --distress is
     printed in a <style> RULE, not an inline style attribute on <html>, so the
     mask stayed fully on at every slider value — including 0. The url() is
     resolved against THIS stylesheet, which is why the default lives here. */
  -webkit-mask-image: var(--erode);
          mask-image: var(--erode);
  -webkit-mask-size: 96px 96px;
          mask-size: 96px 96px;
  -webkit-mask-repeat: repeat;
          mask-repeat: repeat;
  -webkit-mask-mode: luminance;
          mask-mode: luminance;
}
.no-distress .is-distressed {
  -webkit-mask-image: none;
          mask-image: none;
}
@supports not (mask-image: url("")) { .is-distressed { mask-image: none; } }

/* Strike-through that draws itself in — "put you in a box bottle" */
.strike {
  position: relative;
  white-space: nowrap;
}
.strike::after {
  content: "";
  position: absolute;
  left: -.06em; right: -.06em; top: 52%;
  height: .09em;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform calc(.6s * var(--speed)) var(--ease-out) calc(.35s * var(--speed));
}
.is-visible .strike::after, .strike.is-visible::after { transform: scaleX(1); }

/* ==========================================================================
   Layout primitives
   ========================================================================== */

.section {
  position: relative;
  padding-block: var(--section-pad);
  overflow: clip;
}
.section--flush { padding-block: 0; }

.wrap {
  width: min(100% - var(--gutter) * 2, var(--content-max));
  margin-inline: auto;
  position: relative;
  z-index: 2;
}
.wrap--wide { width: min(100% - var(--gutter) * 2, 1600px); }

.center { text-align: center; }

/* Paper grain, per brand guide: grain laid over the whole piece, Screen.
   One fixed, page-wide overlay rather than a blended pseudo-element per
   section — same look, one composited layer instead of a dozen. */
body::after {
  content: "";
  position: fixed; inset: 0;
  background-image: url("../img/textures/grain.png");
  background-size: 220px 220px;
  mix-blend-mode: screen;
  opacity: var(--grain);
  pointer-events: none;
  z-index: 90;
}
@media print { body::after { display: none; } }

/* Angled section seam — Spirit Forward's device, retuned to this palette. */
.seam {
  position: absolute; left: 0; right: 0;
  height: clamp(28px, 3.5vw, 64px);
  z-index: 3; pointer-events: none;
}
.seam--top    { top: -1px; }
.seam--bottom { bottom: -1px; }
.seam svg { width: 100%; height: 100%; display: block; }

/* ==========================================================================
   Drinks + stamp shadows
   The comp's hard-edged shadows are brand *stamps*, not blurred drop shadows
   (branding guide, p6: "If using stamps as a shadow apply Multiply").
   ========================================================================== */

.drink {
  position: relative;
  display: inline-block;
  isolation: isolate;
}
.drink__img {
  position: relative;
  z-index: 2;
  width: 100%; height: auto;
  filter: drop-shadow(0 18px 28px rgb(0 0 0 / .18));
}

/* The cut-outs range from 398x1400 (bottle) to 1182x1337 (rocks glass), so
   sizing by width makes a tall glass tower over a squat one. In any row where
   drinks must read as comparable, size them by height instead. */
.drink--h { height: 100%; }
.drink--h .drink__img { height: 100%; width: auto; }
/* The stamp sits behind the glass on a flat ground, so a plain opaque fill
   reads identically to the guide's Multiply and costs no blend layer. */
.drink__stamp {
  position: absolute;
  z-index: 1;
  left: var(--stamp-x, 38%);
  top:  var(--stamp-y, 16%);
  width: var(--stamp-w, 62%);
  height: var(--stamp-h, auto);
  color: var(--stamp-color, var(--amber));
  pointer-events: none;
}
.drink__stamp svg { width: 100%; height: 100%; fill: currentColor; }
/* Base-anchored: the shadow shares the glass's ground line and runs right,
   which is how every shadow in the comp is drawn. */
.drink__stamp--base {
  top: auto;
  bottom: var(--stamp-b, 0%);
}
/* When a height is given, let the shape stretch to it rather than deriving
   height from the (narrow) wrapper width. */
.drink__stamp[style*="--stamp-h"] svg { width: 100%; height: 100%; }

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-block;
  font-family: var(--font-header);
  text-transform: uppercase;
  font-size: clamp(.9rem, 1.1vw, 1.15rem);
  letter-spacing: .03em;
  line-height: 1;
  padding: .85em 1.5em;
  border: 0; cursor: pointer;
  text-decoration: none;
  background: var(--brown);
  color: var(--cream);
  box-shadow: 5px 5px 0 var(--brown-shadow);
  transition: transform .18s var(--ease-out), box-shadow .18s var(--ease-out),
              background-color .18s var(--ease-out);
}
.btn:hover, .btn:focus-visible {
  transform: translate(-2px, -2px);
  box-shadow: 8px 8px 0 var(--brown-shadow);
}
.btn:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 var(--brown-shadow); }

.btn--orange { background: var(--orange); color: var(--brown); box-shadow: 5px 5px 0 var(--brown); }
.btn--cream  { background: var(--cream);  color: var(--brown); box-shadow: 5px 5px 0 var(--brown-shadow); }

/* ==========================================================================
   Reveals
   ========================================================================== */

.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity var(--reveal-dur) var(--ease-expo),
              transform var(--reveal-dur) var(--ease-expo);
  will-change: transform, opacity;
}
.reveal.is-visible { opacity: 1; transform: none; will-change: auto; }

.reveal--left  { transform: translateX(-40px); }
.reveal--right { transform: translateX(40px); }
.reveal--scale { transform: scale(.92); }
.reveal--stamp { transform: translateY(14px) rotate(-4deg) scale(.9); }

/* Stagger children */
.stagger > * { transition-delay: calc(var(--i, 0) * .09s * var(--speed)); }

/* Word-by-word display reveal — the "animations on the big words" ask.
   No display override here: .words is applied directly to headings and
   paragraphs, and forcing inline-block would drop them onto a shared line. */
.words .word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  /* The clip box has to be a little taller than the 0.8 leading or ascenders
     and descenders get shaved; the negative margin keeps layout identical. */
  padding-block: .06em;
  margin-block: -.06em;
}
.words .word > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform calc(.85s * var(--speed)) var(--ease-expo);
  transition-delay: calc(var(--wi, 0) * .07s * var(--speed));
}
.words.is-visible .word > span { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .words .word > span, .strike::after { transition: none !important; }
  .reveal { opacity: 1; transform: none; }
  .words .word > span { transform: none; }
  .strike::after { transform: scaleX(1); }
}
