  :root {
    --navy: #16253F;
    --navy-deep: #0B1726;
    --navy-lift: #1E3254;
    --cream: #F5EBD2;
    --gold-hi: #F0E0B8;
    --gold: #C0A880;
    --gold-lo: #806840;
    --haze: #E08A1E;   /* was #E09A32, which did not match js/cans.js or CLAUDE.md; this is a 2px rule on bars.html, 5.71:1 on navy */
    --melon: #E0446A;
    --lime: #7CC242;
    --muted: #9FADC4;
    --confirm: #FFF1A8;
    --gold-grad: linear-gradient(135deg, var(--gold-hi), var(--gold) 45%, var(--gold-lo));
    /* Critically damped by default; bounce only where a gesture carried momentum. */
    --settle: cubic-bezier(.22, .61, .36, 1);
    --spring: cubic-bezier(.22, 1.12, .36, 1);
    --gutter: 1.5rem;
  }
  * { box-sizing: border-box; margin: 0; padding: 0; }
  /* color-scheme: the site is permanently dark navy, and without this declaration the browser
     renders the page scrollbar, the <select> option popup on bars.html and the native form chrome
     in light mode over it - and on Windows dark mode the select popup inverts against its own
     styled control. This is not a theme switch; there is no light theme. */
  html { color-scheme: dark; scroll-behavior: smooth; font-size: 100%; background: var(--navy); }
  body {
    background: var(--navy); color: var(--cream);
    font-family: "Libre Franklin", system-ui, sans-serif;
    font-size: 1.0625rem; line-height: 1.6; letter-spacing: 0;
    -webkit-font-smoothing: antialiased; overflow-x: hidden;
  }

  /* Type: tracking and leading are size-specific, never one value for all. */
  /* And no widows. The only text-wrap in the whole stylesheet was on .can-flag, so the hero lede
     ended with "worth it." alone on its last line at 768, 1440 and 1920, and the section headings
     broke the same way. balance for headings (a few lines, evened out), pretty for prose (the
     browser only prevents the orphan, without re-flowing the whole paragraph). */
  h1, h2, h3 { font-family: "Playfair Display", Georgia, serif; font-weight: 900; text-wrap: balance; }
  h1 { font-size: clamp(2.4rem, 6.4vw, 6.5rem); line-height: 1.02; letter-spacing: -0.025em; }   /* the 5rem ceiling capped the hero at 80px on a 1920 screen, where 6.4vw asks for 123px; 6.5rem = 104px, and CLAUDE.md asks for large type */
  h2 { font-size: clamp(1.9rem, 4.6vw, 3.4rem); line-height: 1.06; letter-spacing: -0.02em; }
  h3 { font-size: clamp(1.3rem, 2.2vw, 1.65rem); line-height: 1.15; letter-spacing: -0.01em; }
  .eyebrow {
    font-family: "EB Garamond", Georgia, serif; font-weight: 600;
    font-size: 0.8125rem; line-height: 1.4; letter-spacing: 0.26em; text-transform: uppercase;
    /* Gold is metal, so this keeps a lit ramp - but NOT --gold-grad, which ends at --gold-lo
       (#806840). That is 3.5:1 on the navy ground, under the 4.5:1 floor for text this small, on
       the darkest third of every letter. Stopping at --gold is 6.7:1 and keeps the light source.
       Same reasoning, and the same fix, as .carousel-pos. (The locator's eyebrow used to carry a cream-band
       override; on navy it takes this one, 6.7:1.) */
    background: linear-gradient(135deg, var(--gold-hi), #D8C49A 50%, var(--gold));
    -webkit-background-clip: text; background-clip: text; color: transparent;
  }
  /* Figures that sit in a column, or that change in place, are tabular: proportional digits make
     "01 / 06" jump as the counter advances and misalign the ABV column card to card. */
  /* .slot-n was here: the "03 / 08" counter on a numbered placeholder, deleted 2026-10-31 with
     the placeholders themselves. Nothing in the collage sets numerals any more. */
  .carousel-pos, .can-abv, .can-fact dd { font-variant-numeric: tabular-nums; }
  .script { font-family: "Pinyon Script", cursive; font-weight: 400; }
  .lede, p { text-wrap: pretty; }   /* the other half of the widow fix above */
  .lede { color: var(--muted); font-size: 1.0625rem; max-width: 36rem; }
  /* Specific enough to beat the muted colours it sits inside. */
  .confirm, .fact span.confirm, .spots .confirm, .drink .style .confirm, p .confirm {
    background: var(--confirm); color: #1B1D22; padding: 0 .3em; border-radius: 3px;
    /* Repeat the yellow on every line a wrapped highlight breaks across. Without it an inline box paints
       its background once over the whole fragment chain, and a name that wraps (the flap board's second
       line) would carry the unconfirmed marking on half of itself. */
    -webkit-box-decoration-break: clone; box-decoration-break: clone;
  }
  a { color: inherit; }
  /* apple-design 1: audit every latency on the input path. Without touch-action the browser waits
     to see whether a tap is the first of a double-tap-to-zoom, which is a delay on the cap - the
     page's signature moment - and on every can. It also stops a thumb zooming the carousel
     mid-scroll. */
  button, a, .carousel-can, .carousel-back, .cap-btn, .spots .spot a, .tile a { touch-action: manipulation; }
  .wrap { max-width: 76rem; margin: 0 auto; padding: 0 var(--gutter); }   /* 70rem letterboxed a 1280px design inside 1920; .lede keeps its own 36rem measure, so prose line length is unchanged */

  .skip {
    position: absolute; left: -9999px; top: 0; z-index: 300;
    background: var(--cream); color: var(--navy); padding: .75rem 1.25rem; border-radius: 0 0 4px 0;
  }
  /* :focus-visible, not :focus. The age gate hands focus here when it closes, so on a plain
     mouse click this would otherwise slide a cream bar into the corner of a page nobody is
     keyboarding. A keyboard visitor still sees it: a programmatic focus matches :focus-visible
     when the last interaction was a key. */
  .skip:focus-visible { left: 0; }
  :focus-visible { outline: 2px solid var(--gold-hi); outline-offset: 3px; }
  /* <body> is given tabindex="-1" and focused by js/chrome.js when the age gate is dismissed by
     a pointer, to put the sequential-focus starting point back at the top of the document so the
     first Tab reaches the skip link. Without this cancellation the universal rule above draws a
     gold outline around the entire page - measured on the deployed build, 2026-11-02. <body> is
     not an interactive control, so there is no focus indicator to lose. */
  body[tabindex="-1"]:focus,
  body[tabindex="-1"]:focus-visible { outline: none; }
  /* The gold ring is for the navy ground, which is now every section. The skip link is the one
     cream surface left, and gold on cream is 1.1:1, so it keeps a navy ring (13:1). */
  .skip:focus-visible { outline-color: var(--navy); }

  /* ---- Buttons: feedback on press, never on release ---- */
  .btn {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 2.75rem; padding: .8rem 1.6rem;
    border: 0; cursor: pointer; font: inherit; font-weight: 600; letter-spacing: .01em;
    /* The ramp stops at --gold rather than --gold-lo: the dark navy label over the #806840 end of
       --gold-grad measured 3.3:1, under the floor, and the primary call to action is the last
       place to accept that. Against --gold it is 7.5:1, and the light source survives. */
    background: linear-gradient(135deg, var(--gold-hi), #D8C49A 48%, var(--gold));
    color: #121C2C; border-radius: 2px; text-decoration: none;
    transition: transform .22s var(--settle), filter .22s var(--settle);
  }
  .btn:hover { filter: brightness(1.07); }
  .btn:active { transform: scale(.97); transition-duration: .09s; }
  .btn.ghost { background: none; color: var(--cream); box-shadow: inset 0 0 0 1px var(--gold); }
  .btn.ghost:hover { box-shadow: inset 0 0 0 1px var(--gold-hi); filter: none; }

  /* ---- Nav: translucent layer, content scrolls underneath ---- */
  nav {
    position: fixed; inset: 0 0 auto; z-index: 100;
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: .6rem var(--gutter);
    /* .82, not .66. The bar was tuned when it crossed a cream band, where .66 mixed to a dull grey
       slab. Every section it crosses is navy now, so .82 is simply a glass bar over navy: it reads
       as glass because content and the blur still move under it, and it never turns grey. */
    /* .90 and blur(28px), not .82 and 18px. Over body copy .82 was a correct Apple material, but
       a Playfair 900 h2 at 54px survived the blur and read legibly THROUGH the bar as it crossed
       behind "DRINKS". Still glass - content and the blur still move under it, which was the whole
       reason for .82 - but display type no longer comes through. */
    background: rgba(11, 23, 38, .90);
    backdrop-filter: blur(28px) saturate(170%); -webkit-backdrop-filter: blur(28px) saturate(170%);
    transform: translateY(-110%);
    transition: transform .42s var(--settle);
  }
  nav.show { transform: none; }
  /* Without JS nothing adds .show, so the nav (and its For Bars link) would never appear. */
  html:not(.js) nav { transform: none; }
  /* Scroll edge effect instead of a hard divider: the content just under the bar is blurred, and
     the blur fades out over 1.25rem. A gradient in navy was what used to be here, and it only made
     sense over the navy sections - over a cream ground it would be a dark smear under the bar. A
     blur that fades has no colour of its own, so it reads the same on any ground. */
  nav::after {
    content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 1.25rem;
    backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
    -webkit-mask-image: linear-gradient(#000, transparent);
    mask-image: linear-gradient(#000, transparent);
    pointer-events: none;
  }
  /* Hit areas, not sizes. Every control in the bar reaches the 44px touch floor through padding
     that is cancelled by an equal negative margin, so the finger gets a 44px target and the bar
     keeps the height it was designed at. Without this the nav links were 16px tall and the seal
     34px - fine with a mouse, a coin toss with a thumb. */
  nav .home {
    display: flex; align-items: center; justify-content: center; gap: .6rem; text-decoration: none;
    min-width: 44px; min-height: 44px; margin: -.3rem;
  }
  nav .home img { width: 2.1rem; height: 2.1rem; display: block; }
  nav ul { display: flex; align-items: center; gap: 1.6rem; list-style: none; }
  nav a.link {
    display: inline-flex; align-items: center; min-height: 44px; margin-block: -.875rem;
    font-size: .8125rem; letter-spacing: .14em; text-transform: uppercase;
    text-decoration: none; opacity: .84; transition: opacity .2s var(--settle);
  }
  nav a.link:hover { opacity: 1; }
  /* Feedback on the press, matching .btn - the nav links were the one set of controls on the page
     that answered a tap with nothing until the new section arrived. */
  nav a.link:active { opacity: 1; }
  nav .btn { padding: .5rem 1rem; min-height: 44px; margin-block: -.4rem; font-size: .8125rem; }

  /* ---- Age gate: materializes, not just a fade ---- */
  /* Declared off and switched on only under html.js - the same guard css/bars.css:15-16 has
     carried since 2026-10-28, and the reason is identical: the gate is the 21+ control, and a
     visitor with JavaScript off (or whose js/page.js never loaded - the connection-reset case
     tools/serve.py documents) must never be held behind a fixed, full-viewport overlay whose
     buttons cannot work. The guard was written once, for bars.html, and never back-ported while
     the gate *code* was copy-pasted into js/bars.js. The 2026-10-30 audit measured the result on
     a clean load: display grid, opacity 1, z-index 200, elementFromPoint(centre) === .gate-card,
     with every word of the brand site behind it. tests/structure.test.js now pins this. */
  html:not(.js) .gate { display: none; }
  .gate {
    position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; padding: var(--gutter);
    background: rgba(8, 20, 34, .88);
    backdrop-filter: blur(26px); -webkit-backdrop-filter: blur(26px);
    transition: opacity .42s var(--settle), backdrop-filter .42s var(--settle), visibility .42s;
  }
  .gate.hidden { opacity: 0; visibility: hidden; backdrop-filter: blur(0px); -webkit-backdrop-filter: blur(0px); }
  .gate-card { max-width: 27rem; text-align: center; transition: transform .42s var(--settle); }
  .gate.hidden .gate-card { transform: scale(.96); }
  .gate-card img { width: 8.5rem; height: 8.5rem; margin-bottom: 1.4rem; }
  .gate-card h2 { font-size: clamp(1.7rem, 4vw, 2.2rem); margin-bottom: .5rem; }
  .gate-card p { color: var(--muted); margin-bottom: 1.5rem; }
  .gate-actions { display: flex; gap: .6rem; justify-content: center; flex-wrap: wrap; }
  .gate-no { display: none; margin-top: 1.1rem; color: var(--gold); }


  /* ---- Reveals: visible by default, JS opts in ---- */
  .js .reveal { opacity: 0; transform: translateY(1.6rem); transition: opacity .7s var(--settle), transform .8s var(--settle); }
  .js .reveal.in { opacity: 1; transform: none; }

  section { padding: 6rem 0; scroll-margin-top: 4rem; }   /* the fixed nav is 54px; without this an anchor jump hides the heading behind it the moment the padding changes */
  .sec-head { text-align: center; max-width: 42rem; margin: 0 auto 3rem; }
  .sec-head h2 { margin: .7rem 0 .8rem; }
  .sec-head .lede { margin: 0 auto; }
  .rule { height: 1px; border: 0; background: var(--gold-grad); opacity: .4; }

  footer { background: var(--navy-deep); padding: 3.4rem 0 2.6rem; position: relative; }
  footer::before { content: ""; position: absolute; inset: 0 0 auto; height: 1px; background: var(--gold-grad); opacity: .35; }
  .foot { display: flex; justify-content: space-between; gap: 2rem; flex-wrap: wrap; align-items: flex-start; }
  .foot img { width: 4.6rem; height: 4.6rem; }
  .foot .legal { text-align: right; font-size: .8125rem; color: var(--muted); line-height: 1.9; }
  /* A div, not a nav: the page's `nav` selector is the fixed top bar and would pull this into it. */
  .socials { display: flex; gap: 1.6rem; margin-top: .5rem; font-family: 'EB Garamond', serif; font-size: .875rem; letter-spacing: .16em; text-transform: uppercase; }
  /* 44px tall so a thumb finds it; gold-hi on deep navy is well above 4.5:1. */
  .socials a { display: inline-flex; align-items: center; min-height: 44px; color: var(--gold-hi); text-decoration: none; }
  .socials a:hover { color: var(--cream); }

  @media (max-width: 54rem) {
    nav ul { gap: .9rem; }
    nav .link.hide-sm { display: none; }
    nav .btn, nav a.link { white-space: nowrap; }
    .foot { flex-direction: column; }
    .foot .legal { text-align: left; }
    section { padding: 4.5rem 0; }
  }

  /* Phones down to 320px: Lineup, For Bars and the button must share one row. */
  @media (max-width: 27rem) {
    nav { gap: .5rem; }
    nav ul { gap: .5rem; }
    nav a.link { font-size: .625rem; letter-spacing: .04em; }
    nav .btn { padding: .5rem .6rem; font-size: .6875rem; }
  }

  /* ---- Accessibility preferences ---- */
  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    .js .reveal { opacity: 1; transform: none; transition: opacity .2s linear; }
    .btn:active { transform: none; }
    .gate, .gate-card, nav { transition: opacity .2s linear; }
  }
  @media (prefers-reduced-transparency: reduce) {
    nav { background: var(--navy-deep); backdrop-filter: none; -webkit-backdrop-filter: none; }
    /* The scroll edge is made of blur, so with less transparency asked for there is nothing left
       for it to be: it goes away rather than becoming a hard line. */
    nav::after { display: none; }
    .gate { background: #081422; backdrop-filter: none; -webkit-backdrop-filter: none; }
  }
  @media (prefers-contrast: more) {
    :root { --muted: #CFDAEA; }
    nav { background: var(--navy-deep); }
  }

  /* ---- A contact link is a target, not just text ----
     The distributor's phone and email sit inline in a sentence on both pages, and on a phone that
     is the whole point of them: a bar owner taps the number from behind the bar. Inline, they
     measured 18-20px tall against the 24px minimum. Vertical padding on an INLINE box grows what
     the thumb can hit without growing the line box, so nothing re-spaces and - this is why it is
     not inline-block - a 30-character email address can still break across lines instead of
     forcing the page sideways. */
  a[href^="tel:"], a[href^="mailto:"] { padding-block: .34rem; }

  /* ---- Windows High Contrast ----
     forced-colors replaces the palette and drops background images, so `background-clip: text`
     with `color: transparent` leaves letters clipped to nothing: the eyebrow above every heading
     on the site simply disappears. The gradient is decoration; the words are not. Same answer the
     cream bands already use, pointed at the system colour instead of a brand one. */
  @media (forced-colors: active) {
    .eyebrow {
      background: none;
      -webkit-background-clip: border-box; background-clip: border-box;
      color: CanvasText; -webkit-text-fill-color: CanvasText;
    }
  }
