/* ── CONCIERGE — SHARED STYLESHEET ──
   One file for all six pages. It was six near-identical copies pasted into
   six heads, and the copies had already started to drift; now a change lands
   everywhere or nowhere. Order: the shared core first (tokens, nav, cards,
   quick add, cart, footer, responsive), then the sections only one page
   uses -- shop, product, and the visit/about/arrangements family. */

  /* Newsreader — self-hosted latin subset, optical size pinned to display.
     Georgia is the fallback: it is the face the wordmark is drawn from. */
  @font-face {
    font-family: 'Newsreader';
    font-style: normal;
    font-weight: 300 600;
    font-display: swap;
    src: url('fonts/newsreader-var.woff2') format('woff2');
  }

  :root {
    --serif: 'Newsreader', Georgia, 'Times New Roman', serif;
    /* Secondary type was #bbb (1.92:1) and #ccc (1.61:1) against white, which
       is below the 4.5:1 floor by a wide margin -- unreadable rather than
       quiet. One tone at 5.03:1 for everything subordinate, so it can be
       tuned in one place. */
    --muted: #6f6f6f;
    /* Section rhythm. The page was running 80px between sections and 2px
       between a section title and its content, which read as one continuous
       block of grids rather than as parts. Two values, so the whole page
       breathes or tightens together. */
    --section-gap: 128px;
    --head-gap: 26px;
    /* Cards sat on a 2px hairline gap, which read as one sheet cut into
       pieces rather than as a set of cards. One token so every grid on the
       site opens up together. */
    --card-gap: 16px;
  }

  * { margin: 0; padding: 0; box-sizing: border-box; }

  /* For headings that structure the page for readers and machines but have
     no visual seat, like the homepage h1. */
  .sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }

  body {
    background: #fff;
    color: #111;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-weight: 400;
    font-size: 11px;
    letter-spacing: 0.02em;
    -webkit-font-smoothing: antialiased;
  }

  a { color: inherit; text-decoration: none; }

  /* The hidden attribute loses to any author display rule (.qa-field is
     flex), which left the pick-up time field showing on coffee. Script
     hides things with .hidden; this makes that mean it. */
  [hidden] { display: none !important; }

  /* ── NAV ── */
  nav {
    position: sticky;
    top: 0;
    z-index: 100;
    background: #fff;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 32px;
    height: 48px;
  }

  /* ── LOGO ── */
  .logo {
    display: flex;
    align-items: center;
    gap: 10px;
    color: #111;
  }

  .logo svg { display: block; fill: currentColor; }
  .logo .lk { width: 25.2px; height: 20px; }
  .logo .lw { width: 79.4px; height: 17px; }

  .nav-r {
    display: flex;
    gap: 32px;
    font-size: 11px;
    color: #111;
  }

  .nav-r a { transition: color 0.15s; cursor: pointer; }
  .nav-r a:hover { color: var(--muted); }

  /* ── COLLAPSED NAV ──
     Below 768 the links leave the bar and become a full-height sheet. One set
     of links, restyled, rather than a second copy: the bag count is written to
     a single element and duplicating it would need two. */
  .nav-toggle {
    display: none;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    flex-direction: column;
    justify-content: center;
    align-items: flex-end;
    gap: 5px;
    margin-right: -4px;
  }

  .nav-toggle span {
    display: block;
    width: 20px;
    height: 1px;
    background: #111;
    transition: transform 0.28s ease, opacity 0.2s ease;
  }

  nav.open .nav-toggle span:first-child { transform: translateY(3px) rotate(45deg); }
  nav.open .nav-toggle span:last-child  { transform: translateY(-3px) rotate(-45deg); }

  /* ── HERO ── */
  /* ── PAGE CEILING ──
     The layout had none, so it did not get better on a large display, only
     bigger: at 2560 a product card measures 612x816 and the hero is 1092
     tall. Content stops at 1600 and centres. Written as padding rather than
     max-width so the nav and footer rules still run edge to edge -- capping
     the elements would have cut those short. Below 1664 the max() picks the
     32px gutter and nothing changes. */
  nav, .hero, .shop, footer {
    padding-left: max(32px, calc((100% - 1600px) / 2));
    padding-right: max(32px, calc((100% - 1600px) / 2));
  }

  .hero { padding-top: 24px; padding-bottom: var(--section-gap); }

  .hero-img {
    position: relative;
    width: 100%;
    aspect-ratio: 16/7;
    background: #f2f2f2;
    overflow: hidden;
    margin-bottom: 16px;
  }

  .hero-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
  }

  /* ── HERO SLIDES ──
     Crossfade rather than slide. The frames share no composition, and a
     horizontal move would fight that. */
  .hero-img .slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 1.1s ease;
  }

  .hero-img .slide.on { opacity: 1; }

  /* The new frames are portrait phone photographs, so their subjects sit low
     in a 16/7 window. Raising the image 50px brings the room into the frame
     and drops the empty wall above it. */
  /* A percentage, not a pixel offset. calc(50% - 50px) needs 100px of vertical
     overflow to stay covered, and below 768 the hero is 3/2 against 3/2
     originals -- zero overflow -- so the shift pushed the frame off the top
     and left a 50px band of background at the foot. A percentage is defined
     against whatever overflow exists, so it cannot expose the box: it moves
     315px of desktop overflow by the same 50px and does nothing at all when
     there is nothing to move. */
  .hero-img img.shift-up,
  .visit-hero-img img.shift-up { object-position: center 66%; }

  @media (prefers-reduced-motion: reduce) {
    .hero-img .slide { transition: none; }
  }

  .hero-meta {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
  }

  .hero-sub {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding-bottom: 4px;
  }

  .hero-sub span { display: block; font-size: 11px; color: var(--muted); }
  .hero-sub a { font-size: 11px; color: #111; cursor: pointer; }
  .hero-sub a[target] { color: var(--muted); }
  .hero-sub a:hover { color: #111; }

  .hero-hours {
    display: flex;
    flex-direction: column;
    gap: 6px;
    text-align: right;
    align-self: flex-start;
  }

  .hero-hours span { font-size: 11px; color: var(--muted); }

  /* ── SHOP ── */
  .shop { padding-top: 0; padding-bottom: var(--section-gap); }

  .shop-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: var(--head-gap);
  }

  /* Section and product headlines share the serif. Newsreader runs small at
     a given px against Helvetica, so each of these goes up two. */
  .shop-title {
    font-family: var(--serif);
    font-size: clamp(16px, 1.4vw, 20px);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.07em;
  }

  /* A way out of a section without a second headline: the shop head carries
     the whole catalogue, the About head carries the About page. */
  .head-link {
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    border-bottom: 1px solid #eee;
    transition: color 0.15s, border-color 0.15s;
  }
  .head-link:hover { color: #111; border-color: #111; }

  .grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--card-gap);
  }

  .card { cursor: pointer; position: relative; }

  /* ── KEYBOARD ──
     The homepage cards were divs with onclick: nothing a keyboard or a
     screen reader could reach. Each card now carries a real link stretched
     over it -- same click, same look, and a product page underneath it if
     script is gone. The buy button reveals on focus exactly as it does on
     hover, so tabbing shows the same card a mouse sees. */
  .card-hit { position: absolute; inset: 0; z-index: 1; }
  .card-hit:focus-visible { outline: 2px solid #111; outline-offset: 2px; }
  .card-face { z-index: 2; }
  .shop-card:focus-within .card-cta,
  .drink-card:focus-within .card-cta { opacity: 1; transform: none; pointer-events: auto; }

  .card-img {
    width: 100%;
    aspect-ratio: 3/4;
    background: #f7f7f7;
    overflow: hidden;
    position: relative;
  }

  .card-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
    transition: transform 0.5s ease, opacity 0.4s ease, filter 0.5s ease;
  }

  .card:hover .card-img img { transform: scale(1.1); }

  /* ── SHOP CARD ──
     The blend is named at the top of the packshot, the size and price sit at
     the foot. Hover crossfades to the roasted bean and raises a buy button.
     Scrims at both ends because the packshots are pale at the top and the
     bean shots are dark: white has to hold on either. */
  .shop-card .card-alt {
    position: absolute;
    inset: 0;
    opacity: 0;
  }

  /* The hover: packshot out, beans in. */
  .shop-card:hover .card-base { opacity: 0; }
  .shop-card:hover .card-alt { opacity: 1; }

  .card-face {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 16px;
    color: #fff;
    background: linear-gradient(to bottom,
      rgba(0,0,0,0.58) 0%, rgba(0,0,0,0.22) 20%, rgba(0,0,0,0) 42%,
      rgba(0,0,0,0) 52%, rgba(0,0,0,0.34) 76%, rgba(0,0,0,0.72) 100%);
    pointer-events: none;
  }

  .card-blend {
    font-family: var(--serif);
    font-size: clamp(17px, 1.5vw, 22px);
    font-weight: 400;
    letter-spacing: -0.01em;
    line-height: 1.1;
  }

  .card-meta {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    transition: opacity 0.3s ease;
  }

  /* Two labels, one button. At two-up phone width a card is about 170px wide
     and the full label measures 334px, so the short form is swapped in by
     media query rather than by a resize listener. aria-label carries the full
     sentence either way, and both spans are hidden from the accessibility
     tree so the button is never announced twice. */
  .cta-tight { display: none; }

  .card-cta {
    margin-top: 10px;
    width: 100%;
    padding: 11px 12px;
    border: 0;
    background: #fff;
    color: #111;
    font-family: inherit;
    font-size: 11px;
    letter-spacing: 0.04em;
    cursor: pointer;
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.3s ease, transform 0.3s ease, background 0.15s;
    pointer-events: none;
  }

  .shop-card:hover .card-cta { opacity: 1; transform: translateY(0); pointer-events: auto; }

  .card-cta:hover { background: #f0f0f0; }
  .card-cta:disabled { background: rgba(255,255,255,0.35); color: rgba(255,255,255,0.8); cursor: default; }

  /* ── QUICK ADD ──
     One picture, the size, the count, one dark button. It replaces a half
     page product sheet that opened over the grid and still could not carry a
     tasting note: this is the buy step, and everything else about the coffee
     is a click away on its own page.

     The markup is injected by shopify.js rather than written into each page,
     so the panel on the shop cannot drift from the panel on the homepage. */
  .pdp-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.4);
    z-index: 300;
    overflow-y: auto;
    padding: 32px 16px;
  }

  .pdp-overlay.open { display: flex; align-items: flex-start; justify-content: center; }

  .qa-modal {
    background: #fff;
    width: 100%;
    max-width: 420px;
    margin: auto;
    position: relative;
  }

  .qa-x {
    position: absolute;
    top: 8px; right: 8px;
    z-index: 2;
    width: 34px; height: 34px;
    border: 0;
    background: rgba(255,255,255,0.86);
    font-size: 17px;
    line-height: 1;
    color: #111;
    cursor: pointer;
  }
  .qa-x:hover { background: #fff; }

  .qa-panel { padding: 20px 20px 24px; display: flex; flex-direction: column; gap: 14px; }

  .qa-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }

  .qa-back {
    border: 0; background: none; padding: 0;
    font-family: inherit; font-size: 10px;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--muted); cursor: pointer;
  }
  .qa-back:hover { color: #111; }

  .qa-details { color: #111; border-bottom: 1px solid #ddd; padding-bottom: 2px; margin-right: 30px; transition: border-color 0.15s; }
  .qa-details:hover { border-color: #111; }

  .qa-name { font-family: var(--serif); font-size: 26px; font-weight: 400; line-height: 1.1; letter-spacing: -0.01em; }
  .qa-price { font-size: 11px; color: var(--muted); margin-top: -8px; }

  .qa-field { display: flex; flex-direction: column; gap: 7px; }

  .qa-lbl { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; }

  /* Native selects, restyled rather than rebuilt: a listbox written in
     JavaScript is a keyboard and screen reader problem for no gain, and on a
     phone the system picker is better than anything drawn here. */
  .qa-sel {
    appearance: none;
    -webkit-appearance: none;
    width: 100%;
    padding: 13px 34px 13px 12px;
    border: 1px solid #e4e4e4;
    border-radius: 0;
    background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='6'%3E%3Cpath d='M1 1l3.5 3.5L8 1' fill='none' stroke='%23111'/%3E%3C/svg%3E") no-repeat right 13px center;
    font-family: inherit;
    font-size: 11px;
    letter-spacing: 0.02em;
    color: #111;
    cursor: pointer;
  }
  .qa-sel:focus { outline: none; border-color: #111; }
  .qa-sel:disabled { color: var(--muted); background-image: none; cursor: default; }

  /* ── CART DRAWER ── */
  .cart-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.15);
    z-index: 200;
  }

  .cart-overlay.open { display: block; }

  .cart-drawer {
    position: fixed;
    top: 0;
    right: -400px;
    width: 360px;
    height: 100vh;
    height: 100dvh;
    background: #fff;
    z-index: 201;
    display: flex;
    flex-direction: column;
    transition: right 0.3s ease;
    padding: 32px 24px;
  }

  .cart-drawer.open { right: 0; }

  .cart-drawer-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 32px;
  }

  .cart-drawer-title {
    font-size: 11px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
  }

  .cart-close {
    font-size: 18px;
    cursor: pointer;
    color: var(--muted);
    background: none;
    border: none;
    line-height: 1;
  }

  .cart-close:hover { color: #111; }

  .cart-items { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 20px; }

  .cart-empty { color: var(--muted); font-size: 11px; padding-top: 8px; }

  .ci {
    display: grid;
    grid-template-columns: 56px 1fr auto;
    gap: 14px;
    align-items: start;
  }

  .ci-img { aspect-ratio: 1; background: #f2f2f2; overflow: hidden; }
  .ci-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .ci-name { font-family: var(--serif); font-size: 12px; }
  .ci-sub { font-size: 10px; color: var(--muted); margin-top: 4px; }
  .ci-remove {
    margin-top: 6px; padding: 0; border: 0; background: none;
    font: inherit; font-size: 10px; letter-spacing: 0.04em; color: var(--muted);
    border-bottom: 1px solid #eee; cursor: pointer; transition: color 0.15s, border-color 0.15s;
  }
  .ci-remove:hover { color: #111; border-color: #111; }
  .ci-price { font-size: 11px; }

  .cart-footer { border-top: 1px solid #f0f0f0; padding-top: 24px; margin-top: 24px; display: flex; flex-direction: column; gap: 16px; }

  .cart-total {
    display: flex;
    justify-content: space-between;
    font-size: 11px;
  }

  .cart-total-lbl { color: var(--muted); }

  .atc {
    background: #111;
    color: #fff;
    border: none;
    padding: 14px 16px;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 11px;
    letter-spacing: 0.05em;
    cursor: pointer;
    width: 100%;
    transition: opacity 0.15s;
    text-align: center;
  }

  .atc:hover { opacity: 0.75; }
  .atc:disabled { opacity: 0.4; cursor: default; }

  /* ── FOOTER ── */
  footer {
    padding-top: 48px;
    padding-bottom: 48px;
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    gap: 48px;
    border-top: 1px solid #f0f0f0;
  }

  .ft-logo {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    color: #111;
    margin-bottom: 20px;
  }

  .ft-logo svg { display: block; fill: currentColor; }
  .ft-logo .lk { width: 35.2px; height: 28px; }
  .ft-logo .lw { width: 112px; height: 24px; }

  /* Footer type was #bbb on white, which measures 1.92:1 — the quiet was
     coming from illegibility rather than from restraint. Headings take the
     black and the links take a mid grey at 5.03:1, so the hierarchy is
     carried by weight and case instead of by fading everything out. */
  .ft-addr { font-size: 11px; line-height: 1.9; color: var(--muted); }
  .ft-addr a { color: inherit; transition: color 0.15s; }
  .ft-addr a:hover { color: #111; }
  .ft-city { display: block; margin-top: 14px; }

  /* The logo stands alone in the top row; the Shop and Info columns start
     level with the first address line beside it. 62px of logo plus its
     20px margin. */
  .ft-col { padding-top: 82px; }

  .ft-h {
    font-size: 10px;
    color: #111;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 16px;
  }

  .ft-links { list-style: none; display: flex; flex-direction: column; gap: 12px; }

  .ft-links a { font-size: 11px; color: var(--muted); cursor: pointer; transition: color 0.15s; }
  .ft-links a:hover { color: #111; }

  /* The bottom bar shares the footer's own columns, so the Instagram link
     stands exactly under Shop and the credit under Info's edge, right. */
  .ft-copy {
    grid-column: 1 / -1;
    padding-top: 32px;
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    gap: 48px;
    font-size: 10px;
    color: var(--muted);
  }
  .ft-copy .ft-credit { justify-self: end; }

  /* ── MENU ── */
  .menu-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding-bottom: var(--head-gap);
  }

  /* The pick-up promise is the section's one operational fact, so it reads
     as a line of its own under the headline rather than a footnote, and it
     stays on phones. */
  .menu-pickup {
    margin: -6px 0 var(--head-gap);
    font-size: 13px;
    line-height: 1.6;
    /* One line on anything wider than a phone; the 52ch measure it had
       broke "Downtown LA" onto a second line on desktop. */
  }
  @media (min-width: 769px) { .menu-pickup { white-space: nowrap; } }

  /* ── DRINK GRID ──
     Four up, every card the same size, the row ending exactly on the section
     gutter. The rail this replaces cut its last card at the edge as a scroll
     affordance; read as a broken grid instead, which is a fair verdict when
     every other block on the page ends flush. */
  .menu-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--card-gap);
  }

  /* Drink cards, leads and grid alike. The shop card language: name on the
     picture, ingredients under it, price at the foot, the order button
     rising on hover. No bean layer to crossfade to, so the photograph holds
     through the hover and only the button rises. */
  .menu-lead {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--card-gap);
    margin-bottom: var(--card-gap);
  }
  /* Square, unlike the 3/4 cards everywhere else: two columns wide, the
     portrait crop would tower. */
  .menu-lead .card-img { aspect-ratio: 1/1; }
  /* On a phone the two leads stack full width; they lead. */
  @media (max-width: 480px) {
    .menu-lead { grid-template-columns: 1fr; }
  }
  .drink-card:hover .card-cta { opacity: 1; transform: translateY(0); pointer-events: auto; }
  /* ── MENU MODE ──
     Pick-up ordering lives in Square Online (11 Sep 2026), so the drinks
     read as a menu: the four photographed drinks make a row, as many
     photographs make a two-column grid at every width (Frederik, 11 Sep),
     square like the old two-up leads, and that grid is the section.
     Doubled selector on purpose: .menu-lead has its own phone breakpoint
     later in the file. */
  .drink-card--menu { cursor: default; }
  .menu-pickup a { border-bottom: 1px solid #eee; transition: border-color 0.15s; }
  .menu-pickup a:hover { border-color: #111; }
  .menu-lead.menu-lead--photos { grid-template-columns: repeat(2, 1fr); }
  .drink-ing {
    margin-top: 6px;
    font-size: 11px;
    letter-spacing: 0.03em;
    line-height: 1.6;
    max-width: 44ch;
    opacity: 0.85;
  }
  /* Grid cards carry a smaller ingredient line than the leads. */
  .menu-grid .drink-ing { font-size: 10px; margin-top: 4px; }

  /* The drink hover: a harder push in and the colour drained, so the grid
     reads documentary the moment a card is considered. */
  .drink-card:hover .card-img img { transform: scale(1.22); filter: grayscale(1); }

  /* loading skeleton */
  .skeleton {
    background: linear-gradient(90deg, #f0f0f0 25%, #e8e8e8 50%, #f0f0f0 75%);
    background-size: 200% 100%;
    animation: shimmer 1.2s infinite;
    border-radius: 2px;
  }

  @keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

  /* ── STORY ──
     Facts left, one square picture right. The two founder frames that were
     here moved to the About page: on the homepage this block is a summary
     with a way in, not a gallery. */
  .story-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--card-gap);
    align-items: center;
  }

  /* ── RESPONSIVE ──
     1024 tablet, 768 phone landscape, 480 phone. Gutters step 32 → 24 → 16.
     Below 768 the nav collapses to a sheet, and every grid on the page runs
     two up: shop, merch and drinks alike. Eight products stacked one to a row
     is 3,000px of scrolling and no overview at all; two up you can see the
     range. The card contents are what had to give — the buy label shortens,
     the size and price stack — not the column count. */

  @media (max-width: 1024px) {
    :root { --section-gap: 104px; --head-gap: 22px; --card-gap: 14px; }
    nav, .hero, .shop, footer { padding-left: 24px; padding-right: 24px; }
    .grid { grid-template-columns: repeat(3, 1fr); }
    .menu-grid { grid-template-columns: repeat(3, 1fr); }

    footer { grid-template-columns: 1fr 1fr; gap: 36px; }
  }

  @media (max-width: 768px) {
    :root { --section-gap: 76px; --head-gap: 18px; --card-gap: 10px; }
    nav, .hero, .shop, footer { padding-left: 16px; padding-right: 16px; }
    /* the links leave the bar and become a sheet */
    .nav-toggle { display: flex; }

    .nav-r {
      position: fixed;
      left: 0; right: 0; top: 48px; bottom: 0;
      background: #fff;
      flex-direction: column;
      justify-content: flex-start;
      align-items: stretch;
      gap: 0;
      padding: 4px 16px 40px;
      overflow-y: auto;
      opacity: 0;
      visibility: hidden;
      transform: translateY(-8px);
      transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
      z-index: 95;
    }

    nav.open .nav-r { opacity: 1; visibility: visible; transform: none; }

    .nav-r a {
      font-family: var(--serif);
      font-size: 22px;
      letter-spacing: -0.01em;
      padding: 18px 0;
      border-bottom: 1px solid #f0f0f0;
    }

    .nav-r a:last-child { border-bottom: 0; }

    .hero { padding-bottom: var(--section-gap); }
    .hero-img { aspect-ratio: 3/2; margin-bottom: 14px; }
    .hero-meta { flex-direction: column; align-items: flex-start; gap: 14px; }
    .hero-sub { text-align: left; padding-bottom: 0; }
    .hero-hours { text-align: left; align-self: flex-start; }
    .shop { padding-bottom: var(--section-gap); }
    .grid { grid-template-columns: repeat(2, 1fr); }
    .menu-grid { grid-template-columns: repeat(2, 1fr); }

    /* stacked, picture first: the section should open with an image like the
       ones above it, and the facts read better under it than over it */
    .story-split { grid-template-columns: 1fr; gap: 18px; }
    .story-img, .story-split .abrazo-slides { order: -1; }
    /* Doubled selector on purpose: the base --wide rule sits later in the
       file, so the mobile override needs the extra weight to win. */
    .story-split.story-split--wide { grid-template-columns: 1fr; }

    .menu-head { padding-bottom: var(--head-gap); }
    .pdp-overlay { padding: 12px; }
    .qa-modal { max-width: 460px; }
    .cart-drawer { width: 100%; right: -100%; padding: 24px 16px; }
    footer { padding-top: 36px; gap: 28px; }
    .ft-copy { flex-direction: column; gap: 8px; padding-top: 24px; }
  }

  @media (max-width: 480px) {
    :root { --section-gap: 64px; --head-gap: 16px; --card-gap: 8px; }
    nav, .hero, .shop, footer { padding-left: 14px; padding-right: 14px; }
    .logo { gap: 7px; }
    .logo .lk { width: 20.1px; height: 16px; }
    .logo .lw { width: 60.7px; height: 13px; }
    .shop-head { padding-bottom: var(--head-gap); }
    .menu-grid { grid-template-columns: repeat(2, 1fr); }

    /* Shop card at two up. The face has to carry a name, a size, a price and
       a button in about 145px of usable width. */
    .card-face { padding: 11px; }
    .card-blend { font-size: 16px; }
    .card-meta { flex-direction: column; align-items: flex-start; gap: 2px; }
    .card-cta { font-size: 11px; padding: 12px 8px; margin-top: 9px; }
    .cta-full { display: none; }
    .cta-tight { display: inline; }

    /* the panel takes the width of the phone, less a hairline of backdrop */
    .pdp-overlay { padding: 10px; }
    .qa-modal { max-width: none; }
    .qa-panel { padding: 16px 16px 20px; gap: 12px; }
    .qa-name { font-size: 23px; }

    /* ── FOOTER ON A PHONE ──
       Three stacked lists of 11px grey ran 728px, most of a screen, with
       nothing to hold the eye and no target a thumb could hit. Same links,
       given a shape: brand band, then Shop across the full width with its
       products two up, then Merch and Info side by side. Hairlines between
       the bands rather than gaps, so it reads as sections rather than drift. */
    footer { grid-template-columns: 1fr 1fr; column-gap: 18px; row-gap: 0; padding-top: 40px; padding-bottom: 40px; }

    .ft-brand { grid-column: 1 / -1; padding-bottom: 26px; border-bottom: 1px solid #f0f0f0; }
    .ft-logo { margin-bottom: 16px; }

    .ft-col--shop { grid-column: 1 / -1; padding: 22px 0; border-bottom: 1px solid #f0f0f0; }
    /* Multicol rather than a two-column grid: it runs down the first column
       and then across, which is how a list is read, and it balances itself as
       the catalogue grows or shrinks. A grid would go across-then-down and
       would need the product count hard-coded. */
    /* Three links stack; the two-column split was for a full product list. */
    .ft-col--shop .ft-links li { break-inside: avoid; }
    .ft-col--info { padding-top: 22px; }

    .ft-h { margin-bottom: 2px; }
    .ft-links { gap: 0; }
    .ft-links a { font-size: 13px; }
    .ft-copy { margin-top: 24px; padding-top: 20px; border-top: 1px solid #f0f0f0; }
  }

  .story-facts { display: flex; flex-direction: column; gap: 26px; }
  .story-fact-h {
    font-family: var(--serif);
    font-size: 15px;
    font-weight: 400; /* the fact heads are h3 now; no browser bold */
    margin-bottom: 6px;
  }
  .story-fact p { font-size: 12px; line-height: 1.85; color: var(--muted); max-width: 42ch; }
  .story-more {
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border-bottom: 1px solid #eee;
    align-self: flex-start;
    transition: border-color 0.15s;
  }
  .story-more:hover { border-color: #111; }

  /* ── ABRAZO ──
     Same split as the story block, but the picture takes two thirds: a night
     reads as a room, not a thumbnail. One 3/2 frame running a crossfade of
     five photographs, arrows in the corner, same grayscale as every
     photograph on this page. */
  .story-split--wide { grid-template-columns: 1fr 2fr; }
  .abrazo-slides {
    position: relative;
    aspect-ratio: 3/2;
    overflow: hidden;
    background: #f7f7f7;
  }
  .abrazo-slides .slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 1.1s ease;
  }
  .abrazo-slides .slide.on { opacity: 1; }
  .abrazo-slides .slide img {
    width: 100%; height: 100%; object-fit: cover; display: block;
  }
  /* The homepage strip runs black and white; Arrangements keeps the colour.
     A class on the container, not two copies of the slider. */
  .abrazo-slides--bw .slide img { filter: grayscale(1); }
  .abrazo-arrows { position: absolute; right: 0; bottom: 0; display: flex; z-index: 2; }
  .abrazo-arrows button {
    width: 36px; height: 36px;
    border: 0; padding: 0;
    background: #fff; color: #111;
    font: 14px/1 var(--sans, 'Helvetica Neue', Helvetica, Arial, sans-serif);
    cursor: pointer;
  }
  .abrazo-arrows button:hover { background: #111; color: #fff; }
  @media (prefers-reduced-motion: reduce) {
    .abrazo-slides .slide { transition: none; }
  }

  .story-img { aspect-ratio: 1/1; overflow: hidden; background: #f7f7f7; }
  .story-img img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    /* black and white, as a filter: the colour original stays in the repo */
    filter: grayscale(1);
  }

  /* ── TOUCH ──
     There is no hover on a phone, so anything that only appears on hover would
     never appear at all. The buy button and the photo credits are shown
     outright, and the bean layer is dropped rather than downloaded to sit
     invisible behind the packshot. */
  @media (hover: none) {
    .card-cta { opacity: 1; transform: none; pointer-events: auto; min-height: 44px; }
    .shop-card .card-alt { display: none; }

    /* A footer link was a 24x12 target. A thumb needs 44px, and that is a
       fact about fingers rather than about viewport width, so it hangs off
       the touch query rather than off a breakpoint. */
    .ft-links a { display: flex; align-items: center; min-height: 44px; }
    /* block, not inline-block: inline-block let the phone number ride up onto
       the end of the address line. width:max-content keeps the tap box on the
       text rather than spanning the column. */
    .ft-addr a { display: block; width: max-content; max-width: 100%; padding: 6px 0; }

    /* Text links measured 12 to 17px tall under a thumb. Padding grows the
       tap box to about 44px and the negative margin gives the space back,
       so nothing moves. */
    .hero-sub a, .visit-info a, .head-link, .story-more, .arr-cta a,
    .arr-note a, .detail-val a, .ft-copy a, .pd-crumb a, .menu-pickup a {
      display: inline-block; padding: 15px 0; margin: -15px 0;
    }
    .nav-toggle { width: 44px; height: 44px; margin-right: -11px; }
    .qa-x { width: 44px; height: 44px; top: 4px; right: 4px; }
    .cart-close { padding: 12px; margin: -12px; }
    .abrazo-arrows button { width: 44px; height: 44px; }
    .qa-back, .qa-details { display: inline-block; padding: 12px 0; margin: -12px 0; }
    .ci-remove { display: inline-block; padding: 12px 0; margin: -6px 0 -12px; }
  }

  /* ── SHOP PAGE ──
     The homepage sells a selection from a grid that has to sit between a hero
     and a drink menu. This page has nothing else to do, so the cards get their
     type beneath the picture instead of over it: on a page that is only
     shopping, the name, the price and the button have to be readable at a
     glance, and white type on a scrim is a mood rather than a price tag. */
  .sp-top { padding-top: 44px; padding-bottom: 52px; }
  .sp-title {
    font-family: var(--serif);
    font-size: clamp(40px, 6vw, 86px);
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.025em;
  }
  .sp-intro { font-size: 12px; line-height: 1.85; color: var(--muted); max-width: 46ch; margin-top: 18px; }

  /* Four up, like the grid on the homepage: five coffees and four merch
     items is a catalogue, and a catalogue wants to be seen at once. The
     sections that hold three cards run three up so neither ends on an orphan. */
  .sp-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--card-gap); }

  .sp-card { display: flex; flex-direction: column; cursor: default; }
  .sp-hit { display: block; color: inherit; }
  /* 4/5 against sources that are 3/4 and 4/5: a square would cut a
     quarter off a standing bag, and 3/4 towers at this width. */
  .sp-card .card-img { aspect-ratio: 4/5; }

  /* ── ONE HOVER ──
     Every card on this page answers the same way: the picture eases up a
     little, nothing else. The coffee used to crossfade to a bean shot while
     the merch and the proposals did nothing at all, which read as three
     different kinds of card rather than one catalogue. The bean swap stays on
     the homepage, where it is one device on one grid. */
  .sp-card .card-img img { transition: transform 0.7s cubic-bezier(0.22,1,0.36,1); }
  .sp-card:hover .card-img img { transform: scale(1.04); }
  .sp-name { font-family: var(--serif); font-size: 18px; line-height: 1.2; margin-top: 14px; }
  .sp-sub { font-size: 11px; line-height: 1.7; color: var(--muted); margin-top: 6px; max-width: 36ch; }
  .sp-foot {
    display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
    font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
    margin-top: 12px; padding-top: 11px; border-top: 1px solid #f0f0f0;
  }
  .sp-foot .sp-lead { color: #111; }
  /* Shopify carries a line for two of the five coffees and nothing for the
     rest, so the copy above the rule is ragged by nature. The rule and the
     button are pushed to the foot instead, and a row ends on two straight
     lines rather than on five different ones. */
  .sp-card .sp-foot { margin-top: auto; }
  .sp-add {
    margin-top: 12px; width: 100%; padding: 13px;
    border: 1px solid #111; background: #fff; color: #111;
    font-family: inherit; font-size: 11px; letter-spacing: 0.05em;
    cursor: pointer; transition: background 0.15s, color 0.15s;
  }
  .sp-add:hover { background: #111; color: #fff; }
  .sp-add:disabled { border-color: #ececec; color: var(--muted); background: #fff; cursor: default; }

  .sp-note { font-size: 11px; line-height: 1.8; color: var(--muted); max-width: 46ch; padding-bottom: var(--head-gap); }

  @media (max-width: 1024px) {
    .sp-grid { grid-template-columns: repeat(3, 1fr); }
    .sp-name { font-size: 16px; }
  }

  @media (max-width: 768px) {
    .sp-top { padding-top: 28px; padding-bottom: 36px; }
    .sp-grid { grid-template-columns: repeat(2, 1fr); }
    .sp-sub { display: none; }
    .sp-name { font-size: 15px; margin-top: 10px; }
    .sp-foot { flex-direction: column; gap: 3px; margin-top: 9px; padding-top: 9px; }
  }

  @media (max-width: 480px) {
    .sp-name { font-size: 13px; }
    .sp-add { padding: 12px 8px; }
  }

  /* ── PRODUCT PAGE ──
     Where See Full Details goes. The buy controls are the same two selects and
     the same dark button as the quick add panel, deliberately: the panel is a
     shortcut to this page, so it should not be a different transaction. */
  .pd-wrap { padding-top: 26px; padding-bottom: var(--section-gap); }
  .pd-crumb { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); margin-bottom: 24px; }
  .pd-crumb a { transition: color 0.15s; }
  .pd-crumb a:hover { color: #111; }

  .pd-split { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(32px, 5vw, 72px); align-items: start; }
  .pd-main { aspect-ratio: 1/1; background: #f7f7f7; overflow: hidden; }
  .pd-main img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .pd-thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--card-gap); margin-top: var(--card-gap); }
  .pd-thumb { aspect-ratio: 1/1; overflow: hidden; background: #f7f7f7; border: 0; padding: 0; cursor: pointer; }
  .pd-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: opacity 0.2s; }
  .pd-thumb:hover img { opacity: 0.78; }

  .pd-detail { display: flex; flex-direction: column; gap: 16px; max-width: 440px; }
  .pd-name { font-family: var(--serif); font-size: clamp(32px, 4vw, 54px); font-weight: 400; line-height: 1.04; letter-spacing: -0.02em; }
  .pd-price { font-size: 12px; }
  .pd-desc { font-size: 12px; line-height: 1.9; color: var(--muted); }
  .pd-sizes { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
  .pd-ship { font-size: 11px; line-height: 1.8; color: var(--muted); max-width: 44ch; }
  .pd-ship a { border-bottom: 1px solid #eee; transition: border-color 0.15s; }
  .pd-ship a:hover { border-color: #111; }
  .pd-missing { padding: 60px 0 100px; }
  /* three coffees under the one being read, so the row fills */
  #more-grid { grid-template-columns: repeat(3, 1fr); }
  .pd-missing .pd-name { margin-bottom: 16px; }

  @media (max-width: 768px) {
    .pd-split { grid-template-columns: 1fr; gap: 24px; }
    .pd-detail { max-width: none; }
    .pd-thumbs { grid-template-columns: repeat(4, 1fr); }
  }

  /* ── VISIT / ABOUT / ARRANGEMENTS ──
     The hero with the page name under it, the details grid, the photo grids
     and the arrangement blocks. Shared by the three pages that tell rather
     than sell. */
  .visit-hero { padding: 24px 32px 0; }
  .visit-hero-img { width: 100%; aspect-ratio: 16/7; overflow: hidden; background: #f2f2f2; }
  .visit-hero-img img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: center 30%;
    display: block;
  }
  /* The About hero runs black and white; Visit and Arrangements keep colour. */
  .visit-hero-img--bw img { filter: grayscale(1); }
  .visit-hero-meta { display: flex; justify-content: space-between; align-items: flex-end; padding: 16px 0 48px; }
  .visit-title {
    font-family: var(--serif);
    font-size: clamp(38px, 5.4vw, 76px);
    font-weight: 400;
    letter-spacing: -0.015em;
    line-height: 0.94;
  }
  .visit-info { text-align: right; display: flex; flex-direction: column; gap: 6px; }
  .visit-info span { font-size: 11px; color: var(--muted); display: block; }
  .visit-info a { font-size: 11px; color: #111; transition: color 0.15s; }
  .visit-info a:hover { color: var(--muted); }

  .details {
    padding-top: 32px;
    padding-bottom: var(--section-gap);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--card-gap);
    border-top: 1px solid #f0f0f0;
  }
  .detail-block { display: flex; flex-direction: column; gap: 8px; }
  .city {
    grid-column: 1 / -1;
    font-family: var(--serif);
    font-size: clamp(16px, 1.4vw, 20px);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin-bottom: 10px;
  }
  .details + .details { border-top: 0; padding-top: 0; }
  .detail-lbl { font-size: 9px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--muted); }
  .detail-val { font-size: 11px; color: #111; line-height: 1.8; }
  .detail-val a { border-bottom: 1px solid #eee; transition: border-color 0.15s; }
  .detail-val a:hover { border-color: #111; }

  .photo-grid { padding-top: 0; padding-bottom: var(--section-gap); display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--card-gap); }
  .photo-grid .wide { grid-column: span 2; }
  .photo-cell { overflow: hidden; background: #f7f7f7; }
  .photo-cell img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: center;
    display: block;
    transition: transform 0.6s ease;
    aspect-ratio: 3/4;
  }
  .photo-cell.wide img { aspect-ratio: 16/10; }
  .photo-cell:hover img { transform: scale(1.03); }

  /* The same page ceiling as the selling pages. */
  .visit-hero, .details, .photo-grid, .arr-intro, .arr-rule, .arr-block, .arr-cta, .arr-pair {
    padding-left: max(32px, calc((100% - 1600px) / 2));
    padding-right: max(32px, calc((100% - 1600px) / 2));
  }

  .arr-intro { padding-top: 0; padding-bottom: var(--section-gap); max-width: 46ch; font-size: 13px; line-height: 1.9; color: #111; }
  .arr-block { padding-top: 0; padding-bottom: var(--section-gap); display: grid; grid-template-columns: 1fr 2fr; gap: 32px; align-items: start; }
  .arr-h { font-family: var(--serif); font-size: clamp(20px, 2.1vw, 28px); font-weight: 400; letter-spacing: -0.01em; line-height: 1.1; }
  .arr-body { max-width: 54ch; font-size: 13px; line-height: 1.9; color: #111; }
  /* A block with photographs: the text on the left in its measure, the
     photographs beside it on the right, stacked, square. On a phone the
     photographs follow the text. */
  .arr-body:has(> .arr-media) { max-width: none; display: grid; grid-template-columns: minmax(0, 54ch) minmax(0, 1fr); gap: 32px; align-items: start; }
  .arr-media .arr-img { margin-top: 0; aspect-ratio: 1/1; }
  .arr-media .arr-img + .arr-img { margin-top: var(--card-gap); }
  .arr-body p + p { margin-top: 14px; }
  .arr-body .arr-note { color: var(--muted); font-size: 11px; line-height: 1.8; }
  /* ── WHOLESALE FORM ──
     The quick add panel's field, label and select, plus a text input in the
     same measure. Two columns for the short answers, one for the long. */
  .ws-form { margin-top: 24px; display: grid; grid-template-columns: 1fr 1fr; gap: 16px 18px; }
  .ws-wide { grid-column: 1 / -1; }
  .ws-in {
    width: 100%;
    padding: 13px 12px;
    border: 1px solid #e4e4e4;
    border-radius: 0;
    background: #fff;
    font-family: inherit;
    font-size: 11px;
    color: #111;
  }
  .ws-in::placeholder { color: #b5b5b5; }
  .ws-in:focus { outline: none; border-color: #111; }
  textarea.ws-in { resize: vertical; line-height: 1.6; min-height: 96px; }
  .ws-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
  .ws-note { grid-column: 1 / -1; font-size: 11px; line-height: 1.8; color: var(--muted); }
  .ws-done { margin-top: 24px; padding-top: 18px; border-top: 1px solid #eee; }
  .ws-done:focus { outline: none; }
  @media (max-width: 480px) { .ws-form { grid-template-columns: 1fr; } }

  .arr-img { margin-top: 24px; aspect-ratio: 3/2; overflow: hidden; background: #f7f7f7; }
  .arr-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .arr-rule { height: 1px; background: #f0f0f0; margin: 0 0 56px; }
  .abrazo-copy { margin-top: 18px; }

  .arr-pair { padding-bottom: var(--section-gap); }
  .arr-pair-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--card-gap); }
  .arr-pair-img { aspect-ratio: 1/1; overflow: hidden; background: #f7f7f7; }
  .arr-pair-img img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    filter: grayscale(1);
  }

  .arr-cta { padding-top: 0; padding-bottom: var(--section-gap); display: flex; flex-wrap: wrap; gap: 10px 28px; align-items: baseline; font-size: 13px; }
  .arr-cta a { border-bottom: 1px solid #eee; transition: border-color 0.15s; }
  .arr-cta a:hover { border-color: #111; }
  .arr-cta-right { margin-left: auto; }

  @media (max-width: 1024px) {
    .visit-hero, .details, .photo-grid, .arr-intro, .arr-block, .arr-cta, .arr-pair { padding-left: 24px; padding-right: 24px; }
    .arr-rule { margin-left: 24px; margin-right: 24px; }
    .details { grid-template-columns: repeat(2, 1fr); row-gap: 28px; }
  }
  @media (max-width: 768px) {
    .visit-hero, .details, .photo-grid, .arr-intro, .arr-block, .arr-cta, .arr-pair { padding-left: 16px; padding-right: 16px; }
    .arr-rule { margin-left: 16px; margin-right: 16px; }
    .visit-hero-img { aspect-ratio: 3/2; }
    .visit-hero-meta { flex-direction: column; align-items: flex-start; gap: 14px; padding: 14px 0 36px; }
    .visit-info { text-align: left; }
    .details { padding-bottom: var(--section-gap); }
    .photo-grid { grid-template-columns: repeat(2, 1fr); padding-bottom: var(--section-gap); }
    .photo-grid .wide { grid-column: span 1; }
    .photo-cell.wide img { aspect-ratio: 3/4; }
    .arr-block { grid-template-columns: 1fr; gap: 12px; }
    .arr-body:has(> .arr-media) { grid-template-columns: 1fr; gap: 24px; }
  }
  @media (max-width: 480px) {
    .visit-hero, .details, .photo-grid, .arr-intro, .arr-block, .arr-cta, .arr-pair { padding-left: 14px; padding-right: 14px; }
    .arr-rule { margin-left: 14px; margin-right: 14px; }
    .details { grid-template-columns: 1fr; }
  }

  /* Labels, last in the file on purpose: the desktop sizes it overrides
     sit above it, and equal specificity goes to the later rule.
     Labels, prices and the footer sit at 9 and 10px in the desktop system.
     On a phone that is under the size a thumb-length away reads well, so
     they come up to 11px there; the letterspacing keeps the register. */
  @media (max-width: 480px) {
    .card-meta, .sp-foot, .ft-h, .ft-copy, .qa-lbl, .pd-crumb, .pd-sizes,
    .head-link, .qa-back, .detail-lbl, .ci-sub, .ci-remove { font-size: 11px; }
  }
